mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-06 09:50:28 +00:00
Merge remote-tracking branch 'origin' into lua-tls-api
This commit is contained in:
commit
d372a5820e
6292 changed files with 499430 additions and 169454 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,7 +1,8 @@
|
||||||
# -*- conf -*-
|
# -*- conf -*-
|
||||||
|
|
||||||
/o
|
/o
|
||||||
/.prompt.jtlp
|
/cosmocc
|
||||||
|
/.cosmocc
|
||||||
|
|
||||||
# TODO: Find some way to have Python write to o/
|
# TODO: Find some way to have Python write to o/
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
|
@ -2,23 +2,41 @@
|
||||||
|
|
||||||
We'd love to accept your patches! Please read this guide first.
|
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
|
## Copyright Assignment
|
||||||
|
|
||||||
Please send an email to Justine Tunney <jtunney@gmail.com> stating that
|
The first time you send a pull request, you need to send an email to
|
||||||
you intend to assign her the copyright to the changes you contribute to
|
Justine Tunney <jtunney@gmail.com> stating that you intend to assign her
|
||||||
Cosmopolitan. Please use the same email address you use for git commits
|
the copyright to the changes you contribute to Cosmopolitan. This only
|
||||||
which should only contain original source code from you or other people
|
applies to the code you *choose* to contribute. It only has to happen
|
||||||
who are also assigning copyright. Please note that, if you're employed,
|
once. The email should be sent from an email address associated with
|
||||||
you may need to get your employer's approval beforehand. If you can not
|
your identity. Your email should link to your pull request.
|
||||||
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)
|
|
||||||
|
|
||||||
This is important because we can't produce 12kb single-file executables
|
Please note that in order to give Justine the copyright, it has to be
|
||||||
that comply with license requirements if we have to embed lots of them.
|
yours to give in the first place. If you're employed, then you should
|
||||||
Although that's less of an issue depending on the purpose of the files.
|
get your employer's approval to do this beforehand. Even with big
|
||||||
For example, ownership is much less of a concern in the unit test files
|
companies like Google, this process is quick and painless. Usually we
|
||||||
so you're encouraged to put your copyright on those, provided it's ISC.
|
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.
|
||||||
|
|
||||||
## Style Guide
|
## Style Guide
|
||||||
|
|
||||||
|
|
125
Makefile
125
Makefile
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set et ft=make ts=8 sw=8 fenc=utf-8 :vi ──────────────────────┘
|
||||||
#
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
#
|
#
|
||||||
|
@ -73,10 +73,13 @@ MODE := $(m)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
COMMA := ,
|
||||||
|
PWD := $(shell pwd)
|
||||||
|
|
||||||
# detect wsl2 running cosmopolitan binaries on the host by checking whether:
|
# 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 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 make, in which case cocmd.com's working directory is in wsl
|
||||||
ifneq ($(findstring //wsl.localhost/,$(CURDIR) $(shell pwd)),)
|
ifneq ($(findstring //wsl.localhost/,$(CURDIR) $(PWD)),)
|
||||||
$(warning wsl2 interop is enabled)
|
$(warning wsl2 interop is enabled)
|
||||||
$(error you need to run sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop')
|
$(error you need to run sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop')
|
||||||
endif
|
endif
|
||||||
|
@ -89,14 +92,33 @@ ifeq ($(MAKE_VERSION), 3.81)
|
||||||
$(error please use build/bootstrap/make.com)
|
$(error please use build/bootstrap/make.com)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# provide instructions to non-linux users on unbundling gcc
|
LC_ALL = C
|
||||||
ifeq ($(TOOLCHAIN),) # if TOOLCHAIN isn't defined
|
SOURCE_DATE_EPOCH = 0
|
||||||
ifeq ("$(wildcard o/third_party/gcc/bin/x86_64-linux-cosmo-*)","") # if our gcc isn't unbundled
|
|
||||||
ifneq ($(UNAME_M)-$(UNAME_S), x86_64-Linux) # if this is not amd64 linux
|
ARFLAGS = rcsD
|
||||||
$(error please run tool/cosmocc/fetch.sh)
|
ZFLAGS ?=
|
||||||
endif
|
XARGS ?= xargs -P4 -rs8000
|
||||||
endif
|
DOT ?= dot
|
||||||
endif
|
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 -M2048m -P8192 $(QUOTA)
|
||||||
|
|
||||||
|
IGNORE := $(shell $(MKDIR) $(TMPDIR))
|
||||||
|
|
||||||
# the default build modes is empty string
|
# the default build modes is empty string
|
||||||
# on x86_64 hosts, MODE= is the same as MODE=x86_64
|
# on x86_64 hosts, MODE= is the same as MODE=x86_64
|
||||||
|
@ -110,6 +132,44 @@ MODE := aarch64
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq ($(findstring aarch64,$(MODE)),)
|
||||||
|
ARCH = aarch64
|
||||||
|
HOSTS ?= pi studio freebsdarm
|
||||||
|
else
|
||||||
|
ARCH = x86_64
|
||||||
|
HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd
|
||||||
|
endif
|
||||||
|
|
||||||
|
ZIPOBJ_FLAGS += -a$(ARCH)
|
||||||
|
IGNORE := $(shell $(MKDIR) $(TMPDIR))
|
||||||
|
|
||||||
|
export ADDR2LINE
|
||||||
|
export LC_ALL
|
||||||
|
export MKDIR
|
||||||
|
export MODE
|
||||||
|
export SOURCE_DATE_EPOCH
|
||||||
|
export TMPDIR
|
||||||
|
|
||||||
|
COSMOCC = .cosmocc/3.2
|
||||||
|
TOOLCHAIN = $(COSMOCC)/bin/$(ARCH)-linux-cosmo-
|
||||||
|
DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.2 28b48682595f0f46b45ab381118cdffdabc8fcfa29aa54e301fe6ffe35269f5e)
|
||||||
|
|
||||||
|
AS = $(TOOLCHAIN)as
|
||||||
|
CC = $(TOOLCHAIN)gcc
|
||||||
|
CXX = $(TOOLCHAIN)g++
|
||||||
|
CXXFILT = $(TOOLCHAIN)c++filt
|
||||||
|
LD = $(TOOLCHAIN)ld.bfd
|
||||||
|
NM = $(TOOLCHAIN)nm
|
||||||
|
GCC = $(TOOLCHAIN)gcc
|
||||||
|
STRIP = $(TOOLCHAIN)strip
|
||||||
|
OBJCOPY = $(TOOLCHAIN)objcopy
|
||||||
|
OBJDUMP = $(TOOLCHAIN)objdump
|
||||||
|
ifneq ($(wildcard $(PWD)/$(TOOLCHAIN)addr2line),)
|
||||||
|
ADDR2LINE = $(PWD)/$(TOOLCHAIN)addr2line
|
||||||
|
else
|
||||||
|
ADDR2LINE = $(TOOLCHAIN)addr2line
|
||||||
|
endif
|
||||||
|
|
||||||
# primary build rules
|
# primary build rules
|
||||||
all: o
|
all: o
|
||||||
o: o/$(MODE)
|
o: o/$(MODE)
|
||||||
|
@ -138,7 +198,7 @@ $(warning please run ape/apeinstall.sh if you intend to use landlock make)
|
||||||
$(shell sleep .5)
|
$(shell sleep .5)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
ifeq ($(USE_SYSTEM_TOOLCHAIN),)
|
ifneq ($(TOOLCHAIN),)
|
||||||
.STRICT = 1
|
.STRICT = 1
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
@ -149,8 +209,8 @@ endif
|
||||||
libc/stdbool.h \
|
libc/stdbool.h \
|
||||||
libc/disclaimer.inc \
|
libc/disclaimer.inc \
|
||||||
rwc:/dev/shm \
|
rwc:/dev/shm \
|
||||||
|
rx:cosmocc \
|
||||||
rx:build/bootstrap \
|
rx:build/bootstrap \
|
||||||
rx:o/third_party/gcc \
|
|
||||||
r:build/portcosmo.h \
|
r:build/portcosmo.h \
|
||||||
/proc/stat \
|
/proc/stat \
|
||||||
rw:/dev/null \
|
rw:/dev/null \
|
||||||
|
@ -189,7 +249,6 @@ include libc/calls/BUILD.mk #─┐
|
||||||
include libc/irq/BUILD.mk # ├──SYSTEMS RUNTIME
|
include libc/irq/BUILD.mk # ├──SYSTEMS RUNTIME
|
||||||
include third_party/nsync/BUILD.mk # │ You can issue system calls
|
include third_party/nsync/BUILD.mk # │ You can issue system calls
|
||||||
include libc/runtime/BUILD.mk # │
|
include libc/runtime/BUILD.mk # │
|
||||||
include third_party/double-conversion/BUILD.mk # │
|
|
||||||
include libc/crt/BUILD.mk # │
|
include libc/crt/BUILD.mk # │
|
||||||
include third_party/dlmalloc/BUILD.mk #─┘
|
include third_party/dlmalloc/BUILD.mk #─┘
|
||||||
include libc/mem/BUILD.mk #─┐
|
include libc/mem/BUILD.mk #─┐
|
||||||
|
@ -198,9 +257,9 @@ include third_party/nsync/mem/BUILD.mk # │ You can now use stdio
|
||||||
include libc/proc/BUILD.mk # │ You can now use threads
|
include libc/proc/BUILD.mk # │ You can now use threads
|
||||||
include libc/dlopen/BUILD.mk # │ You can now use processes
|
include libc/dlopen/BUILD.mk # │ You can now use processes
|
||||||
include libc/thread/BUILD.mk # │ You can finally call malloc()
|
include libc/thread/BUILD.mk # │ You can finally call malloc()
|
||||||
include tool/hello/BUILD.mk # │
|
|
||||||
include third_party/zlib/BUILD.mk # │
|
include third_party/zlib/BUILD.mk # │
|
||||||
include libc/stdio/BUILD.mk # │
|
include libc/stdio/BUILD.mk # │
|
||||||
|
include tool/hello/BUILD.mk # │
|
||||||
include libc/time/BUILD.mk # │
|
include libc/time/BUILD.mk # │
|
||||||
include net/BUILD.mk # │
|
include net/BUILD.mk # │
|
||||||
include third_party/vqsort/BUILD.mk # │
|
include third_party/vqsort/BUILD.mk # │
|
||||||
|
@ -213,9 +272,8 @@ include third_party/intel/BUILD.mk # │
|
||||||
include third_party/aarch64/BUILD.mk # │
|
include third_party/aarch64/BUILD.mk # │
|
||||||
include libc/BUILD.mk #─┘
|
include libc/BUILD.mk #─┘
|
||||||
include libc/sock/BUILD.mk #─┐
|
include libc/sock/BUILD.mk #─┐
|
||||||
include libc/dns/BUILD.mk # ├──ONLINE RUNTIME
|
include net/http/BUILD.mk # ├──ONLINE RUNTIME
|
||||||
include net/http/BUILD.mk # │ You can communicate with the network
|
include third_party/musl/BUILD.mk # │ You can communicate with the network
|
||||||
include third_party/musl/BUILD.mk # │
|
|
||||||
include libc/x/BUILD.mk # │
|
include libc/x/BUILD.mk # │
|
||||||
include dsp/scale/BUILD.mk # │
|
include dsp/scale/BUILD.mk # │
|
||||||
include dsp/mpeg/BUILD.mk # │
|
include dsp/mpeg/BUILD.mk # │
|
||||||
|
@ -223,11 +281,18 @@ include dsp/tty/BUILD.mk # │
|
||||||
include dsp/BUILD.mk # │
|
include dsp/BUILD.mk # │
|
||||||
include third_party/stb/BUILD.mk # │
|
include third_party/stb/BUILD.mk # │
|
||||||
include third_party/mbedtls/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/libcxx/BUILD.mk # │
|
||||||
include third_party/ggml/BUILD.mk # │
|
include third_party/openmp/BUILD.mk # │
|
||||||
include third_party/radpajama/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 # │
|
include net/https/BUILD.mk # │
|
||||||
include third_party/regex/BUILD.mk #─┘
|
include third_party/regex/BUILD.mk # │
|
||||||
|
include third_party/bash/BUILD.mk #─┘
|
||||||
include third_party/tidy/BUILD.mk
|
include third_party/tidy/BUILD.mk
|
||||||
include third_party/BUILD.mk
|
include third_party/BUILD.mk
|
||||||
include third_party/nsync/testing/BUILD.mk
|
include third_party/nsync/testing/BUILD.mk
|
||||||
|
@ -235,6 +300,7 @@ include libc/testlib/BUILD.mk
|
||||||
include tool/viz/lib/BUILD.mk
|
include tool/viz/lib/BUILD.mk
|
||||||
include tool/args/BUILD.mk
|
include tool/args/BUILD.mk
|
||||||
include test/posix/BUILD.mk
|
include test/posix/BUILD.mk
|
||||||
|
include test/libcxx/BUILD.mk
|
||||||
include test/tool/args/BUILD.mk
|
include test/tool/args/BUILD.mk
|
||||||
include third_party/linenoise/BUILD.mk
|
include third_party/linenoise/BUILD.mk
|
||||||
include third_party/maxmind/BUILD.mk
|
include third_party/maxmind/BUILD.mk
|
||||||
|
@ -254,7 +320,6 @@ include third_party/argon2/BUILD.mk
|
||||||
include third_party/smallz4/BUILD.mk
|
include third_party/smallz4/BUILD.mk
|
||||||
include third_party/sqlite3/BUILD.mk
|
include third_party/sqlite3/BUILD.mk
|
||||||
include third_party/mbedtls/test/BUILD.mk
|
include third_party/mbedtls/test/BUILD.mk
|
||||||
include third_party/quickjs/BUILD.mk
|
|
||||||
include third_party/lz4cli/BUILD.mk
|
include third_party/lz4cli/BUILD.mk
|
||||||
include third_party/zip/BUILD.mk
|
include third_party/zip/BUILD.mk
|
||||||
include third_party/xxhash/BUILD.mk
|
include third_party/xxhash/BUILD.mk
|
||||||
|
@ -266,6 +331,7 @@ include third_party/python/BUILD.mk
|
||||||
include tool/build/BUILD.mk
|
include tool/build/BUILD.mk
|
||||||
include tool/curl/BUILD.mk
|
include tool/curl/BUILD.mk
|
||||||
include third_party/qemu/BUILD.mk
|
include third_party/qemu/BUILD.mk
|
||||||
|
include third_party/libcxxabi/test/BUILD.mk
|
||||||
include examples/BUILD.mk
|
include examples/BUILD.mk
|
||||||
include examples/pyapp/BUILD.mk
|
include examples/pyapp/BUILD.mk
|
||||||
include examples/pylife/BUILD.mk
|
include examples/pylife/BUILD.mk
|
||||||
|
@ -294,7 +360,6 @@ include test/libc/calls/BUILD.mk
|
||||||
include test/libc/x/BUILD.mk
|
include test/libc/x/BUILD.mk
|
||||||
include test/libc/xed/BUILD.mk
|
include test/libc/xed/BUILD.mk
|
||||||
include test/libc/fmt/BUILD.mk
|
include test/libc/fmt/BUILD.mk
|
||||||
include test/libc/dns/BUILD.mk
|
|
||||||
include test/libc/time/BUILD.mk
|
include test/libc/time/BUILD.mk
|
||||||
include test/libc/proc/BUILD.mk
|
include test/libc/proc/BUILD.mk
|
||||||
include test/libc/stdio/BUILD.mk
|
include test/libc/stdio/BUILD.mk
|
||||||
|
@ -370,7 +435,6 @@ loc: o/$(MODE)/tool/build/summy.com
|
||||||
COSMOPOLITAN_OBJECTS = \
|
COSMOPOLITAN_OBJECTS = \
|
||||||
TOOL_ARGS \
|
TOOL_ARGS \
|
||||||
NET_HTTP \
|
NET_HTTP \
|
||||||
LIBC_DNS \
|
|
||||||
LIBC_SOCK \
|
LIBC_SOCK \
|
||||||
LIBC_NT_WS2_32 \
|
LIBC_NT_WS2_32 \
|
||||||
LIBC_NT_IPHLPAPI \
|
LIBC_NT_IPHLPAPI \
|
||||||
|
@ -378,8 +442,11 @@ COSMOPOLITAN_OBJECTS = \
|
||||||
THIRD_PARTY_GETOPT \
|
THIRD_PARTY_GETOPT \
|
||||||
LIBC_LOG \
|
LIBC_LOG \
|
||||||
LIBC_TIME \
|
LIBC_TIME \
|
||||||
|
THIRD_PARTY_OPENMP \
|
||||||
THIRD_PARTY_MUSL \
|
THIRD_PARTY_MUSL \
|
||||||
THIRD_PARTY_ZLIB_GZ \
|
THIRD_PARTY_ZLIB_GZ \
|
||||||
|
THIRD_PARTY_LIBCXXABI \
|
||||||
|
THIRD_PARTY_LIBUNWIND \
|
||||||
LIBC_STDIO \
|
LIBC_STDIO \
|
||||||
THIRD_PARTY_GDTOA \
|
THIRD_PARTY_GDTOA \
|
||||||
THIRD_PARTY_REGEX \
|
THIRD_PARTY_REGEX \
|
||||||
|
@ -421,7 +488,6 @@ COSMOPOLITAN_H_PKGS = \
|
||||||
APE \
|
APE \
|
||||||
LIBC \
|
LIBC \
|
||||||
LIBC_CALLS \
|
LIBC_CALLS \
|
||||||
LIBC_DNS \
|
|
||||||
LIBC_ELF \
|
LIBC_ELF \
|
||||||
LIBC_FMT \
|
LIBC_FMT \
|
||||||
LIBC_DLOPEN \
|
LIBC_DLOPEN \
|
||||||
|
@ -450,12 +516,16 @@ COSMOPOLITAN_H_PKGS = \
|
||||||
THIRD_PARTY_GETOPT \
|
THIRD_PARTY_GETOPT \
|
||||||
THIRD_PARTY_MUSL \
|
THIRD_PARTY_MUSL \
|
||||||
THIRD_PARTY_ZLIB \
|
THIRD_PARTY_ZLIB \
|
||||||
|
THIRD_PARTY_ZLIB_GZ \
|
||||||
THIRD_PARTY_REGEX
|
THIRD_PARTY_REGEX
|
||||||
|
|
||||||
COSMOCC_PKGS = \
|
COSMOCC_PKGS = \
|
||||||
$(COSMOPOLITAN_H_PKGS) \
|
$(COSMOPOLITAN_H_PKGS) \
|
||||||
THIRD_PARTY_AARCH64 \
|
THIRD_PARTY_AARCH64 \
|
||||||
THIRD_PARTY_LIBCXX \
|
THIRD_PARTY_LIBCXX \
|
||||||
|
THIRD_PARTY_LIBCXXABI \
|
||||||
|
THIRD_PARTY_LIBUNWIND \
|
||||||
|
THIRD_PARTY_OPENMP \
|
||||||
THIRD_PARTY_INTEL
|
THIRD_PARTY_INTEL
|
||||||
|
|
||||||
o/$(MODE)/cosmopolitan.a: \
|
o/$(MODE)/cosmopolitan.a: \
|
||||||
|
@ -480,18 +550,15 @@ o/cosmopolitan.h: o/cosmopolitan.h.txt \
|
||||||
$(wildcard libc/integral/*) \
|
$(wildcard libc/integral/*) \
|
||||||
$(foreach x,$(COSMOPOLITAN_H_PKGS),$($(x)_HDRS)) \
|
$(foreach x,$(COSMOPOLITAN_H_PKGS),$($(x)_HDRS)) \
|
||||||
$(foreach x,$(COSMOPOLITAN_H_PKGS),$($(x)_INCS))
|
$(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.com @$< >>$@
|
||||||
|
|
||||||
o/cosmopolitan.html: private .UNSANDBOXED = 1
|
o/cosmopolitan.html: private .UNSANDBOXED = 1
|
||||||
o/cosmopolitan.html: \
|
o/cosmopolitan.html: \
|
||||||
o/$(MODE)/third_party/chibicc/chibicc.com.dbg \
|
o/$(MODE)/third_party/chibicc/chibicc.com.dbg \
|
||||||
$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))) \
|
$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))) \
|
||||||
$(SRCS) \
|
$(filter-out %.cc,$(SRCS)) \
|
||||||
$(HDRS)
|
$(HDRS)
|
||||||
$(file >$(TMPDIR)/$(subst /,_,$@),$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))))
|
$(file >$(TMPDIR)/$(subst /,_,$@),$(filter-out %.cc,$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS)))))
|
||||||
o/$(MODE)/third_party/chibicc/chibicc.com.dbg -J \
|
o/$(MODE)/third_party/chibicc/chibicc.com.dbg -J \
|
||||||
-fno-common -include libc/integral/normalize.inc -o $@ \
|
-fno-common -include libc/integral/normalize.inc -o $@ \
|
||||||
-DCOSMO @$(TMPDIR)/$(subst /,_,$@)
|
-DCOSMO @$(TMPDIR)/$(subst /,_,$@)
|
||||||
|
|
30
README.md
30
README.md
|
@ -12,10 +12,11 @@ possible performance and the tiniest footprint imaginable.
|
||||||
|
|
||||||
## Background
|
## Background
|
||||||
|
|
||||||
For an introduction to this project, please read the [αcτµαlly pδrταblε
|
For an introduction to this project, please read the [actually portable
|
||||||
εxεcµταblε](https://justine.lol/ape.html) blog post and [cosmopolitan
|
executable](https://justine.lol/ape.html) blog post and [cosmopolitan
|
||||||
libc](https://justine.lol/cosmopolitan/index.html) website. We also have
|
libc](https://justine.lol/cosmopolitan/index.html) website. We also have
|
||||||
[API documentation](https://justine.lol/cosmopolitan/documentation.html).
|
[API
|
||||||
|
documentation](https://justine.lol/cosmopolitan/documentation.html).
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
|
@ -75,18 +76,7 @@ make install
|
||||||
## Cosmopolitan Source Builds
|
## Cosmopolitan Source Builds
|
||||||
|
|
||||||
Cosmopolitan can be compiled from source on any of our supported
|
Cosmopolitan can be compiled from source on any of our supported
|
||||||
platforms. First, you need to download or clone the repository. If
|
platforms. The Makefile will download cosmocc automatically.
|
||||||
you're not using x86-64 Linux then you'll need cosmocc too.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
git clone https://github.com/jart/cosmopolitan cosmo
|
|
||||||
cd cosmo
|
|
||||||
mkdir -p o/third_party/gcc
|
|
||||||
pushd o/third_party/gcc
|
|
||||||
wget https://cosmo.zip/pub/cosmocc/cosmocc.zip
|
|
||||||
unzip cosmocc.zip
|
|
||||||
popd
|
|
||||||
```
|
|
||||||
|
|
||||||
It's recommended that you install a systemwide APE Loader. This command
|
It's recommended that you install a systemwide APE Loader. This command
|
||||||
requires `sudo` access to copy the `ape` command to a system folder and
|
requires `sudo` access to copy the `ape` command to a system folder and
|
||||||
|
@ -102,7 +92,7 @@ guaranteed to be compatible and furthermore includes our extensions for
|
||||||
doing build system sandboxing.
|
doing build system sandboxing.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
o//third_party/gcc/bin/make -j8
|
build/bootstrap/make.com -j8
|
||||||
o//examples/hello.com
|
o//examples/hello.com
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -113,7 +103,7 @@ depends on core LIBC packages.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
rm -rf o//libc o//test
|
rm -rf o//libc o//test
|
||||||
o//third_party/gcc/bin/make o//test/posix/signal_test.com
|
build/bootstrap/make.com o//test/posix/signal_test.com
|
||||||
o//test/posix/signal_test.com
|
o//test/posix/signal_test.com
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -122,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:
|
all the unit tests in the `TEST_POSIX` package, you could say:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
o//third_party/gcc/bin/make o//test/posix
|
build/bootstrap/make.com o//test/posix
|
||||||
```
|
```
|
||||||
|
|
||||||
Cosmopolitan provides a variety of build modes. For example, if you want
|
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:
|
really tiny binaries (as small as 12kb in size) then you'd say:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
o//third_party/gcc/bin/make m=tiny
|
build/bootstrap/make.com m=tiny
|
||||||
```
|
```
|
||||||
|
|
||||||
You can furthermore cut out the bloat of other operating systems, and
|
You can furthermore cut out the bloat of other operating systems, and
|
||||||
have Cosmopolitan become much more similar to Musl Libc.
|
have Cosmopolitan become much more similar to Musl Libc.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
o//third_party/gcc/bin/make m=tinylinux
|
build/bootstrap/make.com m=tinylinux
|
||||||
```
|
```
|
||||||
|
|
||||||
For further details, see [//build/config.mk](build/config.mk).
|
For further details, see [//build/config.mk](build/config.mk).
|
||||||
|
|
19
ape/BUILD.mk
19
ape/BUILD.mk
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
#
|
#
|
||||||
# OVERVIEW
|
# OVERVIEW
|
||||||
#
|
#
|
||||||
|
@ -78,7 +78,8 @@ APE_LOADER_FLAGS = \
|
||||||
$<
|
$<
|
||||||
|
|
||||||
o/$(MODE)/ape/ape.elf: o/$(MODE)/ape/ape.elf.dbg
|
o/$(MODE)/ape/ape.elf: o/$(MODE)/ape/ape.elf.dbg
|
||||||
$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -g $< $@
|
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -g $< $@
|
||||||
|
@$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@
|
||||||
|
|
||||||
o/$(MODE)/ape/ape.elf.dbg: \
|
o/$(MODE)/ape/ape.elf.dbg: \
|
||||||
o/$(MODE)/ape/start.o \
|
o/$(MODE)/ape/start.o \
|
||||||
|
@ -88,7 +89,7 @@ o/$(MODE)/ape/ape.elf.dbg: \
|
||||||
@$(COMPILE) -ALINK.elf $(LD) $(APE_LOADER_LDFLAGS) -o $@ $(patsubst %.lds,-T %.lds,$^)
|
@$(COMPILE) -ALINK.elf $(LD) $(APE_LOADER_LDFLAGS) -o $@ $(patsubst %.lds,-T %.lds,$^)
|
||||||
|
|
||||||
o/$(MODE)/ape/loader.o: ape/loader.c ape/ape.h
|
o/$(MODE)/ape/loader.o: ape/loader.c ape/ape.h
|
||||||
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=1 -g $(APE_LOADER_FLAGS)
|
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=33 -g $(APE_LOADER_FLAGS)
|
||||||
o/$(MODE)/ape/start.o: ape/start.S
|
o/$(MODE)/ape/start.o: ape/start.S
|
||||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||||
o/$(MODE)/ape/launch.o: ape/launch.S
|
o/$(MODE)/ape/launch.o: ape/launch.S
|
||||||
|
@ -167,14 +168,11 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
|
||||||
libc/macros.internal.h \
|
libc/macros.internal.h \
|
||||||
libc/nexgen32e/uart.internal.h \
|
libc/nexgen32e/uart.internal.h \
|
||||||
libc/calls/metalfile.internal.h \
|
libc/calls/metalfile.internal.h \
|
||||||
libc/nexgen32e/vidya.internal.h \
|
|
||||||
libc/nt/pedef.internal.h \
|
libc/nt/pedef.internal.h \
|
||||||
libc/runtime/e820.internal.h \
|
libc/runtime/e820.internal.h \
|
||||||
libc/runtime/mman.internal.h \
|
libc/runtime/mman.internal.h \
|
||||||
libc/runtime/pc.internal.h \
|
libc/runtime/pc.internal.h \
|
||||||
libc/sysv/consts/prot.h \
|
libc/sysv/consts/prot.h \
|
||||||
ape/blink-linux-aarch64.gz \
|
|
||||||
ape/blink-xnu-aarch64.gz \
|
|
||||||
o/$(MODE)/ape/ape.elf
|
o/$(MODE)/ape/ape.elf
|
||||||
@$(COMPILE) \
|
@$(COMPILE) \
|
||||||
-AOBJECTIFY.S \
|
-AOBJECTIFY.S \
|
||||||
|
@ -198,14 +196,11 @@ o/$(MODE)/ape/ape-copy-self.o: \
|
||||||
libc/macros.internal.h \
|
libc/macros.internal.h \
|
||||||
libc/nexgen32e/uart.internal.h \
|
libc/nexgen32e/uart.internal.h \
|
||||||
libc/calls/metalfile.internal.h \
|
libc/calls/metalfile.internal.h \
|
||||||
libc/nexgen32e/vidya.internal.h \
|
|
||||||
libc/nt/pedef.internal.h \
|
libc/nt/pedef.internal.h \
|
||||||
libc/runtime/e820.internal.h \
|
libc/runtime/e820.internal.h \
|
||||||
libc/runtime/mman.internal.h \
|
libc/runtime/mman.internal.h \
|
||||||
libc/runtime/pc.internal.h \
|
libc/runtime/pc.internal.h \
|
||||||
libc/sysv/consts/prot.h \
|
libc/sysv/consts/prot.h
|
||||||
ape/blink-linux-aarch64.gz \
|
|
||||||
ape/blink-xnu-aarch64.gz
|
|
||||||
@$(COMPILE) \
|
@$(COMPILE) \
|
||||||
-AOBJECTIFY.S \
|
-AOBJECTIFY.S \
|
||||||
$(OBJECTIFY.S) \
|
$(OBJECTIFY.S) \
|
||||||
|
@ -264,10 +259,6 @@ endif
|
||||||
o/$(MODE)/ape/ape.o: ape/ape.S
|
o/$(MODE)/ape/ape.o: ape/ape.S
|
||||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
@$(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: \
|
o/$(MODE)/ape/ape.lds: \
|
||||||
ape/ape.lds \
|
ape/ape.lds \
|
||||||
ape/macros.internal.h \
|
ape/macros.internal.h \
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│
|
/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│
|
||||||
│ vi: set noet sts=2 tw=2 fenc=utf-8 :vi │
|
│ vi: set et sts=2 sw=2 fenc=utf-8 :vi │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/thread/tls.h"
|
#include "libc/thread/tls.h"
|
||||||
|
|
||||||
|
|
198
ape/ape-m1.c
198
ape/ape-m1.c
|
@ -35,9 +35,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define pagesz 16384
|
#define pagesz 16384
|
||||||
#define VARNAME "COSMOPOLITAN_PROGRAM_EXECUTABLE="
|
|
||||||
#define VARSIZE (sizeof(VARNAME) - 1)
|
|
||||||
/* maximum path size that cosmo can take */
|
/* maximum path size that cosmo can take */
|
||||||
#define PATHSIZE (PATH_MAX < 1024 ? PATH_MAX : 1024)
|
#define PATHSIZE (PATH_MAX < 1024 ? PATH_MAX : 1024)
|
||||||
#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24)
|
#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24)
|
||||||
|
@ -105,36 +103,39 @@ struct Syslib {
|
||||||
char *(*dlerror)(void);
|
char *(*dlerror)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ELFCLASS32 1
|
#define ELFCLASS32 1
|
||||||
#define ELFDATA2LSB 1
|
#define ELFDATA2LSB 1
|
||||||
#define EM_AARCH64 183
|
#define EM_AARCH64 183
|
||||||
#define ET_EXEC 2
|
#define ET_EXEC 2
|
||||||
#define ET_DYN 3
|
#define ET_DYN 3
|
||||||
#define PT_LOAD 1
|
#define PT_LOAD 1
|
||||||
#define PT_DYNAMIC 2
|
#define PT_DYNAMIC 2
|
||||||
#define PT_INTERP 3
|
#define PT_INTERP 3
|
||||||
#define EI_CLASS 4
|
#define EI_CLASS 4
|
||||||
#define EI_DATA 5
|
#define EI_DATA 5
|
||||||
#define PF_X 1
|
#define PF_X 1
|
||||||
#define PF_W 2
|
#define PF_W 2
|
||||||
#define PF_R 4
|
#define PF_R 4
|
||||||
#define AT_PHDR 3
|
#define AT_PHDR 3
|
||||||
#define AT_PHENT 4
|
#define AT_PHENT 4
|
||||||
#define AT_PHNUM 5
|
#define AT_PHNUM 5
|
||||||
#define AT_PAGESZ 6
|
#define AT_PAGESZ 6
|
||||||
#define AT_BASE 7
|
#define AT_BASE 7
|
||||||
#define AT_ENTRY 9
|
#define AT_FLAGS 8
|
||||||
#define AT_UID 11
|
#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
|
||||||
#define AT_EUID 12
|
#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
|
||||||
#define AT_GID 13
|
#define AT_ENTRY 9
|
||||||
#define AT_EGID 14
|
#define AT_UID 11
|
||||||
#define AT_HWCAP 16
|
#define AT_EUID 12
|
||||||
#define AT_HWCAP2 16
|
#define AT_GID 13
|
||||||
#define AT_SECURE 23
|
#define AT_EGID 14
|
||||||
#define AT_RANDOM 25
|
#define AT_HWCAP 16
|
||||||
#define AT_EXECFN 31
|
#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 */
|
/* from the xnu codebase */
|
||||||
#define _COMM_PAGE_START_ADDRESS 0x0000000FFFFFC000ul
|
#define _COMM_PAGE_START_ADDRESS 0x0000000FFFFFC000ul
|
||||||
|
@ -203,11 +204,8 @@ struct PathSearcher {
|
||||||
unsigned long namelen;
|
unsigned long namelen;
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *syspath;
|
const char *syspath;
|
||||||
char varname[VARSIZE];
|
|
||||||
char path[PATHSIZE];
|
char path[PATHSIZE];
|
||||||
};
|
};
|
||||||
_Static_assert(offsetof(struct PathSearcher, varname) + VARSIZE ==
|
|
||||||
offsetof(struct PathSearcher, path), "struct layout");
|
|
||||||
|
|
||||||
struct ApeLoader {
|
struct ApeLoader {
|
||||||
struct PathSearcher ps;
|
struct PathSearcher ps;
|
||||||
|
@ -321,28 +319,13 @@ __attribute__((__noreturn__)) static void Pexit(const char *c, int failed,
|
||||||
}
|
}
|
||||||
|
|
||||||
static char AccessCommand(struct PathSearcher *ps, unsigned long pathlen) {
|
static char AccessCommand(struct PathSearcher *ps, unsigned long pathlen) {
|
||||||
if (!pathlen && *ps->name != '/') {
|
if (pathlen + 1 + ps->namelen + 1 > sizeof(ps->path)) {
|
||||||
if (!getcwd(ps->path, sizeof(ps->path) - 1 - ps->namelen)) {
|
|
||||||
Pexit("getcwd", -errno, "failed");
|
|
||||||
}
|
|
||||||
pathlen = strlen(ps->path);
|
|
||||||
} else if (pathlen + 1 + ps->namelen + 1 > sizeof(ps->path)) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (pathlen && ps->path[pathlen - 1] != '/') ps->path[pathlen++] = '/';
|
if (pathlen && ps->path[pathlen - 1] != '/') ps->path[pathlen++] = '/';
|
||||||
memmove(ps->path + pathlen, ps->name, ps->namelen);
|
memmove(ps->path + pathlen, ps->name, ps->namelen);
|
||||||
ps->path[pathlen + ps->namelen] = 0;
|
ps->path[pathlen + ps->namelen] = 0;
|
||||||
if (!access(ps->path, X_OK)) {
|
return !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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char SearchPath(struct PathSearcher *ps) {
|
static char SearchPath(struct PathSearcher *ps) {
|
||||||
|
@ -368,12 +351,8 @@ static char FindCommand(struct PathSearcher *ps) {
|
||||||
ps->path[0] = 0;
|
ps->path[0] = 0;
|
||||||
|
|
||||||
/* paths are always 100% taken literally when a slash exists
|
/* paths are always 100% taken literally when a slash exists
|
||||||
$ ape foo/bar.com arg1 arg2 */
|
$ ape foo/bar.com arg1 arg2
|
||||||
if (memchr(ps->name, '/', ps->namelen)) {
|
we don't run files in the current directory
|
||||||
return AccessCommand(ps, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we don't run files in the current directory
|
|
||||||
$ ape foo.com arg1 arg2
|
$ ape foo.com arg1 arg2
|
||||||
unless $PATH has an empty string entry, e.g.
|
unless $PATH has an empty string entry, e.g.
|
||||||
$ expert PATH=":/bin"
|
$ expert PATH=":/bin"
|
||||||
|
@ -381,8 +360,8 @@ static char FindCommand(struct PathSearcher *ps) {
|
||||||
however we will execute this
|
however we will execute this
|
||||||
$ ape - foo.com foo.com arg1 arg2
|
$ ape - foo.com foo.com arg1 arg2
|
||||||
because cosmo's execve needs it */
|
because cosmo's execve needs it */
|
||||||
if (ps->literally && AccessCommand(ps, 0)) {
|
if (ps->literally || memchr(ps->name, '/', ps->namelen)) {
|
||||||
return 1;
|
return AccessCommand(ps, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* otherwise search for name on $PATH */
|
/* otherwise search for name on $PATH */
|
||||||
|
@ -392,7 +371,8 @@ static char FindCommand(struct PathSearcher *ps) {
|
||||||
static char *Commandv(struct PathSearcher *ps, const char *name,
|
static char *Commandv(struct PathSearcher *ps, const char *name,
|
||||||
const char *syspath) {
|
const char *syspath) {
|
||||||
ps->syspath = syspath ? syspath : "/bin:/usr/local/bin:/usr/bin";
|
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 (ps->namelen + 1 > sizeof(ps->path)) return 0;
|
||||||
if (FindCommand(ps)) {
|
if (FindCommand(ps)) {
|
||||||
return ps->path;
|
return ps->path;
|
||||||
|
@ -563,7 +543,8 @@ static long sys_pselect(int nfds, fd_set *readfds, fd_set *writefds,
|
||||||
__attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
|
__attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
|
||||||
long *sp, struct ElfEhdr *e,
|
long *sp, struct ElfEhdr *e,
|
||||||
struct ElfPhdr *p,
|
struct ElfPhdr *p,
|
||||||
struct Syslib *lib) {
|
struct Syslib *lib,
|
||||||
|
char *path) {
|
||||||
long rc;
|
long rc;
|
||||||
int prot;
|
int prot;
|
||||||
int flags;
|
int flags;
|
||||||
|
@ -734,11 +715,11 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
register long *x0 __asm__("x0") = sp;
|
register long *x0 __asm__("x0") = sp;
|
||||||
|
register char *x2 __asm__("x2") = path;
|
||||||
|
register int x3 __asm__("x3") = 8; /* _HOSTXNU */
|
||||||
register struct Syslib *x15 __asm__("x15") = lib;
|
register struct Syslib *x15 __asm__("x15") = lib;
|
||||||
register long x16 __asm__("x16") = e->e_entry;
|
register long x16 __asm__("x16") = e->e_entry;
|
||||||
__asm__ volatile("mov\tx1,#0\n\t"
|
__asm__ volatile("mov\tx1,#0\n\t"
|
||||||
"mov\tx2,#0\n\t"
|
|
||||||
"mov\tx3,#0\n\t"
|
|
||||||
"mov\tx4,#0\n\t"
|
"mov\tx4,#0\n\t"
|
||||||
"mov\tx5,#0\n\t"
|
"mov\tx5,#0\n\t"
|
||||||
"mov\tx6,#0\n\t"
|
"mov\tx6,#0\n\t"
|
||||||
|
@ -767,7 +748,7 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
|
||||||
"mov\tx0,#0\n\t"
|
"mov\tx0,#0\n\t"
|
||||||
"br\tx16"
|
"br\tx16"
|
||||||
: /* no outputs */
|
: /* no outputs */
|
||||||
: "r"(x0), "r"(x15), "r"(x16)
|
: "r"(x0), "r"(x2), "r"(x3), "r"(x15), "r"(x16)
|
||||||
: "memory");
|
: "memory");
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
@ -870,28 +851,30 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
|
||||||
auxv[7] = ebuf->ehdr.e_entry;
|
auxv[7] = ebuf->ehdr.e_entry;
|
||||||
auxv[8] = AT_PAGESZ;
|
auxv[8] = AT_PAGESZ;
|
||||||
auxv[9] = pagesz;
|
auxv[9] = pagesz;
|
||||||
auxv[10] = AT_UID;
|
auxv[10] = AT_FLAGS;
|
||||||
auxv[11] = getuid();
|
auxv[11] = M->ps.literally ? AT_FLAGS_PRESERVE_ARGV0 : 0;
|
||||||
auxv[12] = AT_EUID;
|
auxv[12] = AT_UID;
|
||||||
auxv[13] = geteuid();
|
auxv[13] = getuid();
|
||||||
auxv[14] = AT_GID;
|
auxv[14] = AT_EUID;
|
||||||
auxv[15] = getgid();
|
auxv[15] = geteuid();
|
||||||
auxv[16] = AT_EGID;
|
auxv[16] = AT_GID;
|
||||||
auxv[17] = getegid();
|
auxv[17] = getgid();
|
||||||
auxv[18] = AT_HWCAP;
|
auxv[18] = AT_EGID;
|
||||||
auxv[19] = 0xffb3ffffu;
|
auxv[19] = getegid();
|
||||||
auxv[20] = AT_HWCAP2;
|
auxv[20] = AT_HWCAP;
|
||||||
auxv[21] = 0x181;
|
auxv[21] = 0xffb3ffffu;
|
||||||
auxv[22] = AT_SECURE;
|
auxv[22] = AT_HWCAP2;
|
||||||
auxv[23] = issetugid();
|
auxv[23] = 0x181;
|
||||||
auxv[24] = AT_RANDOM;
|
auxv[24] = AT_SECURE;
|
||||||
auxv[25] = (long)M->rando;
|
auxv[25] = issetugid();
|
||||||
auxv[26] = AT_EXECFN;
|
auxv[26] = AT_RANDOM;
|
||||||
auxv[27] = (long)execfn;
|
auxv[27] = (long)M->rando;
|
||||||
auxv[28] = 0;
|
auxv[28] = AT_EXECFN;
|
||||||
|
auxv[29] = (long)execfn;
|
||||||
|
auxv[30] = 0;
|
||||||
|
|
||||||
/* we're now ready to load */
|
/* we're now ready to load */
|
||||||
Spawn(exe, fd, sp, e, p, &M->lib);
|
Spawn(exe, fd, sp, e, p, &M->lib, M->ps.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv, char **envp) {
|
int main(int argc, char **argv, char **envp) {
|
||||||
|
@ -900,8 +883,7 @@ int main(int argc, char **argv, char **envp) {
|
||||||
struct ApeLoader *M;
|
struct ApeLoader *M;
|
||||||
long *sp, *sp2, *auxv;
|
long *sp, *sp2, *auxv;
|
||||||
union ElfEhdrBuf *ebuf;
|
union ElfEhdrBuf *ebuf;
|
||||||
char *p, *pe, *exe, *prog,
|
char *p, *pe, *exe, *prog, *execfn;
|
||||||
*execfn, *shell, **varpos;
|
|
||||||
|
|
||||||
/* allocate loader memory in program's arg block */
|
/* allocate loader memory in program's arg block */
|
||||||
n = sizeof(struct ApeLoader);
|
n = sizeof(struct ApeLoader);
|
||||||
|
@ -964,16 +946,16 @@ int main(int argc, char **argv, char **envp) {
|
||||||
M->lib.dlerror = dlerror;
|
M->lib.dlerror = dlerror;
|
||||||
|
|
||||||
/* getenv("_") is close enough to at_execfn */
|
/* getenv("_") is close enough to at_execfn */
|
||||||
execfn = argc > 0 ? argv[0] : 0;
|
execfn = 0;
|
||||||
varpos = 0;
|
|
||||||
for (i = 0; envp[i]; ++i) {
|
for (i = 0; envp[i]; ++i) {
|
||||||
if (envp[i][0] == '_' && envp[i][1] == '=') {
|
if (envp[i][0] == '_' && envp[i][1] == '=') {
|
||||||
execfn = envp[i] + 2;
|
execfn = envp[i] + 2;
|
||||||
} else if (!memcmp(VARNAME, envp[i], VARSIZE)) {
|
|
||||||
assert(!varpos);
|
|
||||||
varpos = envp + i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
prog = GetEnv(envp + i + 1, "executable_path");
|
||||||
|
if (!execfn) {
|
||||||
|
execfn = prog;
|
||||||
|
}
|
||||||
|
|
||||||
/* sneak the system five abi back out of args */
|
/* sneak the system five abi back out of args */
|
||||||
sp = (long *)(argv - 1);
|
sp = (long *)(argv - 1);
|
||||||
|
@ -982,7 +964,7 @@ int main(int argc, char **argv, char **envp) {
|
||||||
/* create new bottom of stack for spawned program
|
/* create new bottom of stack for spawned program
|
||||||
system v abi aligns this on a 16-byte boundary
|
system v abi aligns this on a 16-byte boundary
|
||||||
grows down the alloc by poking the guard pages */
|
grows down the alloc by poking the guard pages */
|
||||||
n = (auxv - sp + !varpos + AUXV_WORDS + 1) * sizeof(long);
|
n = (auxv - sp + AUXV_WORDS + 1) * sizeof(long);
|
||||||
sp2 = (long *)__builtin_alloca(n);
|
sp2 = (long *)__builtin_alloca(n);
|
||||||
if ((long)sp2 & 15) ++sp2;
|
if ((long)sp2 & 15) ++sp2;
|
||||||
for (; n > 0; n -= pagesz) {
|
for (; n > 0; n -= pagesz) {
|
||||||
|
@ -991,18 +973,12 @@ int main(int argc, char **argv, char **envp) {
|
||||||
memmove(sp2, sp, (auxv - sp) * sizeof(long));
|
memmove(sp2, sp, (auxv - sp) * sizeof(long));
|
||||||
argv = (char **)(sp2 + 1);
|
argv = (char **)(sp2 + 1);
|
||||||
envp = (char **)(sp2 + 1 + argc + 1);
|
envp = (char **)(sp2 + 1 + argc + 1);
|
||||||
if (varpos) {
|
|
||||||
varpos = (char **)((long *)varpos - sp + sp2);
|
|
||||||
} else {
|
|
||||||
varpos = envp + i++;
|
|
||||||
*(envp + i) = 0;
|
|
||||||
}
|
|
||||||
auxv = (long *)(envp + i + 1);
|
auxv = (long *)(envp + i + 1);
|
||||||
sp = sp2;
|
sp = sp2;
|
||||||
|
|
||||||
/* interpret command line arguments */
|
/* interpret command line arguments */
|
||||||
if ((M->ps.indirect = argc > 0 ? GetIndirectOffset(argv[0]) : 0)) {
|
if ((M->ps.indirect = GetIndirectOffset(prog))) {
|
||||||
/* if argv[0] is $prog.ape, then we strip off the .ape and run
|
/* 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
|
$prog. This allows you to use symlinks to trick the OS when
|
||||||
a native executable is required. For example, let's say you
|
a native executable is required. For example, let's say you
|
||||||
want to use the APE binary /opt/cosmos/bin/bash as a system
|
want to use the APE binary /opt/cosmos/bin/bash as a system
|
||||||
|
@ -1011,13 +987,7 @@ int main(int argc, char **argv, char **envp) {
|
||||||
but it will if you say:
|
but it will if you say:
|
||||||
ln -sf /usr/local/bin/ape /opt/cosmos/bin/bash.ape
|
ln -sf /usr/local/bin/ape /opt/cosmos/bin/bash.ape
|
||||||
and then use #!/opt/cosmos/bin/bash.ape instead. */
|
and then use #!/opt/cosmos/bin/bash.ape instead. */
|
||||||
M->ps.literally = 0;
|
M->ps.literally = 1;
|
||||||
if (*argv[0] == '-' && (shell = GetEnv(envp, "SHELL")) &&
|
|
||||||
!StrCmp(argv[0] + 1, BaseName(shell))) {
|
|
||||||
execfn = prog = shell;
|
|
||||||
} else {
|
|
||||||
prog = (char *)sp[1];
|
|
||||||
}
|
|
||||||
argc = sp[0];
|
argc = sp[0];
|
||||||
argv = (char **)(sp + 1);
|
argv = (char **)(sp + 1);
|
||||||
} else if ((M->ps.literally = argc >= 3 && !StrCmp(argv[1], "-"))) {
|
} else if ((M->ps.literally = argc >= 3 && !StrCmp(argv[1], "-"))) {
|
||||||
|
@ -1031,9 +1001,9 @@ int main(int argc, char **argv, char **envp) {
|
||||||
} else if (argc < 2) {
|
} else if (argc < 2) {
|
||||||
Emit("usage: ape PROG [ARGV1,ARGV2,...]\n"
|
Emit("usage: ape PROG [ARGV1,ARGV2,...]\n"
|
||||||
" ape - PROG [ARGV0,ARGV1,...]\n"
|
" ape - PROG [ARGV0,ARGV1,...]\n"
|
||||||
" ($0 = PROG.ape) [ARGV1,ARGV2,...]\n"
|
" PROG.ape [ARGV1,ARGV2,...]\n"
|
||||||
"actually portable executable loader silicon 1.9\n"
|
"actually portable executable loader silicon 1.10\n"
|
||||||
"copyright 2023 justine alexandra roberts tunney\n"
|
"copyrights 2023 justine alexandra roberts tunney\n"
|
||||||
"https://justine.lol/ape.html\n");
|
"https://justine.lol/ape.html\n");
|
||||||
_exit(1);
|
_exit(1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1061,12 +1031,6 @@ int main(int argc, char **argv, char **envp) {
|
||||||
}
|
}
|
||||||
pe = ebuf->buf + rc;
|
pe = ebuf->buf + rc;
|
||||||
|
|
||||||
/* inject program executable as first environment variable,
|
|
||||||
swapping the old first variable for it. */
|
|
||||||
memmove(M->ps.varname, VARNAME, VARSIZE);
|
|
||||||
*varpos = *envp;
|
|
||||||
*envp = M->ps.varname;
|
|
||||||
|
|
||||||
/* generate some hard random data */
|
/* generate some hard random data */
|
||||||
if ((rc = sys_getentropy(M->rando, sizeof(M->rando))) < 0) {
|
if ((rc = sys_getentropy(M->rando, sizeof(M->rando))) < 0) {
|
||||||
Pexit(argv[0], rc, "getentropy");
|
Pexit(argv[0], rc, "getentropy");
|
||||||
|
|
57
ape/ape.S
57
ape/ape.S
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=asm ts=8 tw=8 fenc=utf-8 :vi │
|
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
|
@ -592,9 +592,7 @@ ape_disk:
|
||||||
|
|
||||||
#ifdef APE_IS_SHELL_SCRIPT
|
#ifdef APE_IS_SHELL_SCRIPT
|
||||||
apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
|
apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
|
||||||
.ascii "m=$(/bin/uname -m 2>/dev/null) || "
|
.ascii "m=$(uname -m 2>/dev/null) || m=x86_64\n"
|
||||||
.ascii "m=$(/usr/bin/uname -m 2>/dev/null) || "
|
|
||||||
.ascii "m=x86_64\n"
|
|
||||||
|
|
||||||
.ascii "if [ \"$m\" = x86_64 ] || [ \"$m\" = amd64 ]; then\n"
|
.ascii "if [ \"$m\" = x86_64 ] || [ \"$m\" = amd64 ]; then\n"
|
||||||
// Until all operating systems can be updated to support APE,
|
// Until all operating systems can be updated to support APE,
|
||||||
|
@ -617,15 +615,15 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
|
||||||
.ascii APE_VERSION_STR
|
.ascii APE_VERSION_STR
|
||||||
.ascii "\"\n"
|
.ascii "\"\n"
|
||||||
.ascii "[ -x \"$t\" ] || {\n"
|
.ascii "[ -x \"$t\" ] || {\n"
|
||||||
.ascii "/bin/mkdir -p \"${t%/*}\" &&\n"
|
.ascii "mkdir -p \"${t%/*}\" &&\n"
|
||||||
.ascii "/bin/dd if=\"$o\" of=\"$t.$$\" skip="
|
.ascii "dd if=\"$o\" of=\"$t.$$\" skip="
|
||||||
.shstub ape_loader_dd_skip,2
|
.shstub ape_loader_dd_skip,2
|
||||||
.ascii " count="
|
.ascii " count="
|
||||||
.shstub ape_loader_dd_count,2
|
.shstub ape_loader_dd_count,2
|
||||||
.ascii " bs=64 2>/dev/null\n"
|
.ascii " bs=64 2>/dev/null\n"
|
||||||
#if SupportsXnu()
|
#if SupportsXnu()
|
||||||
.ascii "[ -d /Applications ] && "
|
.ascii "[ -d /Applications ] && "
|
||||||
.ascii "/bin/dd if=\"$t.$$\""
|
.ascii "dd if=\"$t.$$\""
|
||||||
.ascii " of=\"$t.$$\""
|
.ascii " of=\"$t.$$\""
|
||||||
.ascii " skip=5"
|
.ascii " skip=5"
|
||||||
.ascii " count=8"
|
.ascii " count=8"
|
||||||
|
@ -633,8 +631,8 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
|
||||||
.ascii " conv=notrunc"
|
.ascii " conv=notrunc"
|
||||||
.ascii " 2>/dev/null\n"
|
.ascii " 2>/dev/null\n"
|
||||||
#endif /* SupportsXnu() */
|
#endif /* SupportsXnu() */
|
||||||
.ascii "/bin/chmod 755 \"$t.$$\"\n"
|
.ascii "chmod 755 \"$t.$$\"\n"
|
||||||
.ascii "/bin/mv -f \"$t.$$\" \"$t\"\n"
|
.ascii "mv -f \"$t.$$\" \"$t\"\n"
|
||||||
.ascii "}\n"
|
.ascii "}\n"
|
||||||
.ascii "exec \"$t\" \"$o\" \"$@\"\n"
|
.ascii "exec \"$t\" \"$o\" \"$@\"\n"
|
||||||
.ascii "}\n"
|
.ascii "}\n"
|
||||||
|
@ -650,9 +648,9 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
|
||||||
.ascii "t=\"${TMPDIR:-${HOME:-.}}/$0\"\n"
|
.ascii "t=\"${TMPDIR:-${HOME:-.}}/$0\"\n"
|
||||||
.ascii "[ x\"$1\" != x--assimilate ] || [ ! -e \"$t\" ] && {\n"
|
.ascii "[ x\"$1\" != x--assimilate ] || [ ! -e \"$t\" ] && {\n"
|
||||||
.ascii "[ x\"$1\" != x--assimilate ] && {\n"
|
.ascii "[ x\"$1\" != x--assimilate ] && {\n"
|
||||||
.ascii "/bin/mkdir -p \"${t%/*}\" 2>/dev/null\n"
|
.ascii "mkdir -p \"${t%/*}\" 2>/dev/null\n"
|
||||||
.ascii "/bin/cp -f \"$o\" \"$t.$$\" &&\n"
|
.ascii "cp -f \"$o\" \"$t.$$\" &&\n"
|
||||||
.ascii "/bin/mv -f \"$t.$$\" \"$t\" || exit 120\n"
|
.ascii "mv -f \"$t.$$\" \"$t\" || exit 120\n"
|
||||||
.ascii "o=\"$t\"\n"
|
.ascii "o=\"$t\"\n"
|
||||||
.ascii "}\n"
|
.ascii "}\n"
|
||||||
#endif /* APE_NO_MODIFY_SELF */
|
#endif /* APE_NO_MODIFY_SELF */
|
||||||
|
@ -683,7 +681,7 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
|
||||||
.ascii "exec 7<&-\n"
|
.ascii "exec 7<&-\n"
|
||||||
#if SupportsXnu()
|
#if SupportsXnu()
|
||||||
.ascii "[ -d /Applications ] && "
|
.ascii "[ -d /Applications ] && "
|
||||||
.ascii "/bin/dd if=\"$o\""
|
.ascii "dd if=\"$o\""
|
||||||
.ascii " of=\"$o\""
|
.ascii " of=\"$o\""
|
||||||
.ascii " bs=8"
|
.ascii " bs=8"
|
||||||
.ascii " skip="
|
.ascii " skip="
|
||||||
|
@ -702,38 +700,9 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
|
||||||
#endif /* APE_NO_MODIFY_SELF */
|
#endif /* APE_NO_MODIFY_SELF */
|
||||||
.ascii "exit $?\n"
|
.ascii "exit $?\n"
|
||||||
.ascii "fi\n" // x86_64
|
.ascii "fi\n" // x86_64
|
||||||
// ...
|
.ascii "echo error: this ape binary only supports x86_64 >&2\n"
|
||||||
// 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=$(/bin/uname -s 2>/dev/null) || "
|
|
||||||
.ascii "s=$(/usr/bin/uname -s 2>/dev/null) || "
|
|
||||||
.ascii "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 "exit 1\n"
|
.ascii "exit 1\n"
|
||||||
.previous
|
.endobj apesh
|
||||||
|
|
||||||
#ifdef APE_LOADER
|
#ifdef APE_LOADER
|
||||||
.section .ape.loader,"a",@progbits
|
.section .ape.loader,"a",@progbits
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define COSMOPOLITAN_APE_APE_H_
|
#define COSMOPOLITAN_APE_APE_H_
|
||||||
|
|
||||||
#define APE_VERSION_MAJOR 1
|
#define APE_VERSION_MAJOR 1
|
||||||
#define APE_VERSION_MINOR 9
|
#define APE_VERSION_MINOR 10
|
||||||
#define APE_VERSION_STR APE_VERSION_STR_(APE_VERSION_MAJOR, APE_VERSION_MINOR)
|
#define APE_VERSION_STR APE_VERSION_STR_(APE_VERSION_MAJOR, APE_VERSION_MINOR)
|
||||||
#define APE_VERSION_NOTE APE_VERSION_NOTE_(APE_VERSION_MAJOR, APE_VERSION_MINOR)
|
#define APE_VERSION_NOTE APE_VERSION_NOTE_(APE_VERSION_MAJOR, APE_VERSION_MINOR)
|
||||||
|
|
||||||
|
|
31
ape/ape.lds
31
ape/ape.lds
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│
|
/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│
|
||||||
│ vi: set noet sts=2 tw=2 fenc=utf-8 :vi │
|
│ vi: set et sts=2 sw=2 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
|
@ -229,7 +229,6 @@ SECTIONS {
|
||||||
|
|
||||||
/* Real Mode */
|
/* Real Mode */
|
||||||
KEEP(*(.head))
|
KEEP(*(.head))
|
||||||
KEEP(*(.apesh))
|
|
||||||
KEEP(*(.text.head))
|
KEEP(*(.text.head))
|
||||||
|
|
||||||
/* Executable & Linkable Format */
|
/* Executable & Linkable Format */
|
||||||
|
@ -238,10 +237,6 @@ SECTIONS {
|
||||||
KEEP(*(.elf.phdrs))
|
KEEP(*(.elf.phdrs))
|
||||||
ape_phdrs_end = .;
|
ape_phdrs_end = .;
|
||||||
|
|
||||||
KEEP(*(.emushprologue))
|
|
||||||
KEEP(*(.emush))
|
|
||||||
KEEP(*(.emushepilogue))
|
|
||||||
|
|
||||||
/* OpenBSD */
|
/* OpenBSD */
|
||||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
||||||
ape_note = .;
|
ape_note = .;
|
||||||
|
@ -301,7 +296,6 @@ SECTIONS {
|
||||||
KEEP(*(.textwindowsprologue))
|
KEEP(*(.textwindowsprologue))
|
||||||
*(.text.windows)
|
*(.text.windows)
|
||||||
KEEP(*(.textwindowsepilogue))
|
KEEP(*(.textwindowsepilogue))
|
||||||
KEEP(*(.blink))
|
|
||||||
*(SORT_BY_ALIGNMENT(.text.modernity))
|
*(SORT_BY_ALIGNMENT(.text.modernity))
|
||||||
*(SORT_BY_ALIGNMENT(.text.modernity.*))
|
*(SORT_BY_ALIGNMENT(.text.modernity.*))
|
||||||
*(SORT_BY_ALIGNMENT(.text.hot))
|
*(SORT_BY_ALIGNMENT(.text.hot))
|
||||||
|
@ -613,29 +607,6 @@ SHSTUB2(ape_loader_dd_count,
|
||||||
? ROUNDUP(ape_loader_end - ape_loader, CONSTANT(COMMONPAGESIZE)) / 64
|
? ROUNDUP(ape_loader_end - ape_loader, CONSTANT(COMMONPAGESIZE)) / 64
|
||||||
: 0);
|
: 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()
|
#if SupportsMetal()
|
||||||
v_ape_realsectors = MIN(0x70000 - IMAGE_BASE_REAL, ROUNDUP(RVA(_ezip), 512)) / 512;
|
v_ape_realsectors = MIN(0x70000 - IMAGE_BASE_REAL, ROUNDUP(RVA(_ezip), 512)) / 512;
|
||||||
v_ape_realbytes = v_ape_realsectors * 512;
|
v_ape_realbytes = v_ape_realsectors * 512;
|
||||||
|
|
|
@ -10,73 +10,98 @@ if [ ! -f ape/loader.c ]; then
|
||||||
cd "$COSMO" || exit
|
cd "$COSMO" || exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -x build/bootstrap/make.com ]; then
|
||||||
|
MAKE=build/bootstrap/make.com
|
||||||
|
else
|
||||||
|
MAKE=make
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$(id -u)" -eq 0 ]; then
|
if [ "$(id -u)" -eq 0 ]; then
|
||||||
SUDO=
|
SUDO=
|
||||||
else
|
elif command -v sudo >/dev/null 2>&1; then
|
||||||
SUDO=sudo
|
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
|
||||||
|
if [ x"$(uname -s)" = xLinux ]; then
|
||||||
|
INSTALL="install -o root -g root -m 755"
|
||||||
|
else
|
||||||
|
INSTALL="install -o root -g wheel -m 755"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
INSTALL="cp -f"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Actually Portable Executable (APE) Installer" >&2
|
echo "Actually Portable Executable (APE) Installer" >&2
|
||||||
echo "Author: Justine Tunney <jtunney@gmail.com>" >&2
|
echo "Author: Justine Tunney <jtunney@gmail.com>" >&2
|
||||||
|
|
||||||
# special installation process for apple silicon
|
# special installation process for apple silicon
|
||||||
if [ "$(uname -s)" = "Darwin" ] && [ "$(uname -m)" = "arm64" ]; then
|
if [ x"$(uname -s)" = xDarwin ] && [ x"$(uname -m)" = xarm64 ]; then
|
||||||
echo "cc -O -o $TMPDIR/ape.$$ ape/ape-m1.c" >&2
|
echo "cc -O -o $TMPDIR/ape.$$ ape/ape-m1.c" >&2
|
||||||
cc -O -o "$TMPDIR/ape.$$" ape/ape-m1.c || exit
|
cc -O -o "$TMPDIR/ape.$$" ape/ape-m1.c || exit
|
||||||
|
trap 'rm "$TMPDIR/ape.$$"' EXIT
|
||||||
if [ ! -d /usr/local/bin ]; then
|
if [ ! -d /usr/local/bin ]; then
|
||||||
echo "$SUDO mkdir -p /usr/local/bin" >&2
|
echo "$SUDO mkdir -p /usr/local/bin" >&2
|
||||||
$SUDO mkdir -p /usr/local/bin || exit
|
$SUDO mkdir -p /usr/local/bin || exit
|
||||||
fi
|
fi
|
||||||
echo "$SUDO mv -f $TMPDIR/ape.$$ /usr/local/bin/ape" >&2
|
echo "$SUDO $INSTALL $TMPDIR/ape.$$ /usr/local/bin/ape" >&2
|
||||||
$SUDO mv -f "$TMPDIR/ape.$$" /usr/local/bin/ape || exit
|
$SUDO $INSTALL "$TMPDIR/ape.$$" /usr/local/bin/ape || exit
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ x"$(uname -m)" = xarm64 ] || [ x"$(uname -m)" = xaarch64 ]; then
|
||||||
|
MODE=aarch64
|
||||||
|
EXT=elf
|
||||||
|
BEXT=aarch64
|
||||||
|
elif [ x"$(uname -m)" = xx86_64 ]; then
|
||||||
|
MODE=
|
||||||
|
if [ x"$(uname -s)" = xDarwin ]; then
|
||||||
|
EXT=macho
|
||||||
|
else
|
||||||
|
EXT=elf
|
||||||
|
fi
|
||||||
|
BEXT=$EXT
|
||||||
|
else
|
||||||
|
echo "unsupported architecture $(uname -m)" >&2
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# INSTALL APE LOADER SYSTEMWIDE
|
# INSTALL APE LOADER SYSTEMWIDE
|
||||||
|
|
||||||
if [ -f o/depend ] && make -j8 o//ape; then
|
if [ -f o/$MODE/depend ] && $MAKE -j8 o/$MODE/ape; then
|
||||||
echo "successfully recompiled ape loader" >&2
|
echo "successfully recompiled ape loader" >&2
|
||||||
elif [ -x o//ape/ape.elf ] && [ -x o//ape/ape.macho ]; then
|
elif [ -x o/$MODE/ape/ape.$EXT ]; then
|
||||||
echo "using ape loader you compiled earlier" >&2
|
echo "using ape loader you compiled earlier" >&2
|
||||||
elif [ -d build/bootstrap ]; then
|
elif [ -d build/bootstrap ]; then
|
||||||
# if make isn't being used then it's unlikely the user changed the sources
|
# if make isn't being used then it's unlikely the user changed the sources
|
||||||
# in that case the prebuilt binaries should be completely up-to-date
|
# in that case the prebuilt binaries should be completely up-to-date
|
||||||
echo "using prebuilt ape loader from cosmo repo" >&2
|
echo "using prebuilt ape loader from cosmo repo" >&2
|
||||||
mkdir -p o//ape || exit
|
mkdir -p o/$MODE/ape || exit
|
||||||
cp -af build/bootstrap/ape.elf o//ape/ape.elf || exit
|
cp -af build/bootstrap/ape.$BEXT o/$MODE/ape/ape.$EXT || exit
|
||||||
cp -af build/bootstrap/ape.macho o//ape/ape.macho || exit
|
|
||||||
else
|
else
|
||||||
echo "no cosmopolitan libc repository here" >&2
|
echo "no cosmopolitan libc repository here" >&2
|
||||||
echo "fetching ape loader from justine.lol" >&2
|
echo "fetching ape loader from justine.lol" >&2
|
||||||
mkdir -p o//ape || exit
|
mkdir -p o/$MODE/ape || exit
|
||||||
if command -v wget >/dev/null 2>&1; then
|
if command -v wget >/dev/null 2>&1; then
|
||||||
wget -qO o//ape/ape.elf https://justine.lol/ape.elf || exit
|
wget -qO o/$MODE/ape/ape.$EXT https://justine.lol/ape.$BEXT || exit
|
||||||
wget -qO o//ape/ape.macho https://justine.lol/ape.macho || exit
|
|
||||||
else
|
else
|
||||||
curl -Rso o//ape/ape.elf https://justine.lol/ape.elf || exit
|
curl -Rso o/$MODE/ape/ape.$EXT https://justine.lol/ape.$BEXT || exit
|
||||||
curl -Rso o//ape/ape.macho https://justine.lol/ape.macho || exit
|
|
||||||
fi
|
fi
|
||||||
chmod +x o//ape/ape.elf || exit
|
chmod +x o/$MODE/ape/ape.$EXT || exit
|
||||||
chmod +x o//ape/ape.macho || exit
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$(uname -s)" = "Darwin" ]; then
|
if ! [ /usr/bin/ape -nt o/$MODE/ape/ape.$EXT ]; then
|
||||||
if ! [ /usr/bin/ape -nt o//ape/ape.macho ]; then
|
echo >&2
|
||||||
echo >&2
|
echo "installing o/$MODE/ape/ape.$EXT to /usr/bin/ape" >&2
|
||||||
echo "installing o//ape/ape.macho to /usr/bin/ape" >&2
|
echo "$SUDO $INSTALL o/$MODE/ape/ape.$EXT /usr/bin/ape" >&2
|
||||||
echo "$SUDO cp -f o//ape/ape.macho /usr/bin/ape" >&2
|
$SUDO $INSTALL o/$MODE/ape/ape.$EXT /usr/bin/ape || exit
|
||||||
$SUDO cp -f o//ape/ape.macho /usr/bin/ape || exit
|
echo "done" >&2
|
||||||
echo "done" >&2
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if ! [ /usr/bin/ape -nt o//ape/ape.elf ]; then
|
|
||||||
echo >&2
|
|
||||||
echo "installing o//ape/ape.elf to /usr/bin/ape" >&2
|
|
||||||
echo "$SUDO mv -f o//ape/ape.elf /usr/bin/ape" >&2
|
|
||||||
$SUDO cp -f o//ape/ape.elf /usr/bin/ape || exit
|
|
||||||
echo "done" >&2
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
|
@ -11,8 +11,13 @@ fi
|
||||||
|
|
||||||
if [ "$UID" = "0" ]; then
|
if [ "$UID" = "0" ]; then
|
||||||
SUDO=
|
SUDO=
|
||||||
else
|
elif command -v sudo >/dev/null 2>&1; then
|
||||||
SUDO=sudo
|
SUDO=sudo
|
||||||
|
elif command -v doas >/dev/null 2>&1; then
|
||||||
|
SUDO=doas
|
||||||
|
else
|
||||||
|
echo "need root or sudo" >&2
|
||||||
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -54,8 +59,7 @@ for x in .ape \
|
||||||
.ape-1.7 \
|
.ape-1.7 \
|
||||||
.ape-1.8 \
|
.ape-1.8 \
|
||||||
.ape-1.9 \
|
.ape-1.9 \
|
||||||
.ape-blink-0.9.2 \
|
.ape-1.10; do
|
||||||
.ape-blink-1.0.0; do
|
|
||||||
rm -f \
|
rm -f \
|
||||||
~/$x \
|
~/$x \
|
||||||
/tmp/$x \
|
/tmp/$x \
|
||||||
|
|
Binary file not shown.
Binary file not shown.
12
ape/launch.S
12
ape/launch.S
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=asm ts=8 tw=8 fenc=utf-8 :vi │
|
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
|
@ -31,17 +31,16 @@
|
||||||
//
|
//
|
||||||
// @param rdi is passed through as-is
|
// @param rdi is passed through as-is
|
||||||
// @param rsi is address of entrypoint (becomes zero)
|
// @param rsi is address of entrypoint (becomes zero)
|
||||||
// @param rdx is stack pointer (becomes zero)
|
// @param rdx is passed through as-is
|
||||||
// @param rcx is passed through as-is
|
// @param rcx is passed through as-is
|
||||||
|
// @param r8 is stack pointer (becomes zero)
|
||||||
// @noreturn
|
// @noreturn
|
||||||
Launch:
|
Launch:
|
||||||
#ifdef __aarch64__
|
#ifdef __aarch64__
|
||||||
|
|
||||||
mov x16,x1
|
mov x16,x1
|
||||||
mov sp,x2
|
mov sp,x4
|
||||||
mov x1,0
|
mov x1,0
|
||||||
mov x2,0
|
|
||||||
mov x3,0
|
|
||||||
mov x4,0
|
mov x4,0
|
||||||
mov x5,0
|
mov x5,0
|
||||||
mov x6,0
|
mov x6,0
|
||||||
|
@ -71,6 +70,7 @@ Launch:
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
mov %r8,%rsp
|
||||||
xor %r8d,%r8d
|
xor %r8d,%r8d
|
||||||
xor %r9d,%r9d
|
xor %r9d,%r9d
|
||||||
xor %r10d,%r10d
|
xor %r10d,%r10d
|
||||||
|
@ -79,8 +79,6 @@ Launch:
|
||||||
xor %r13d,%r13d
|
xor %r13d,%r13d
|
||||||
xor %r14d,%r14d
|
xor %r14d,%r14d
|
||||||
xor %r15d,%r15d
|
xor %r15d,%r15d
|
||||||
mov %rdx,%rsp
|
|
||||||
xor %edx,%edx
|
|
||||||
push %rsi
|
push %rsi
|
||||||
xor %esi,%esi
|
xor %esi,%esi
|
||||||
xor %ebp,%ebp
|
xor %ebp,%ebp
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=asm ts=8 tw=8 fenc=utf-8 :vi │
|
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
|
|
193
ape/loader.c
193
ape/loader.c
|
@ -87,6 +87,8 @@
|
||||||
#define MIN(X, Y) ((Y) > (X) ? (X) : (Y))
|
#define MIN(X, Y) ((Y) > (X) ? (X) : (Y))
|
||||||
#define MAX(X, Y) ((Y) < (X) ? (X) : (Y))
|
#define MAX(X, Y) ((Y) < (X) ? (X) : (Y))
|
||||||
|
|
||||||
|
#define PATH_MAX 1024 /* XXX verify */
|
||||||
|
|
||||||
#define SupportsLinux() (SUPPORT_VECTOR & LINUX)
|
#define SupportsLinux() (SUPPORT_VECTOR & LINUX)
|
||||||
#define SupportsXnu() (SUPPORT_VECTOR & XNU)
|
#define SupportsXnu() (SUPPORT_VECTOR & XNU)
|
||||||
#define SupportsFreebsd() (SUPPORT_VECTOR & FREEBSD)
|
#define SupportsFreebsd() (SUPPORT_VECTOR & FREEBSD)
|
||||||
|
@ -111,41 +113,44 @@
|
||||||
#define EXTERN_C
|
#define EXTERN_C
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define O_RDONLY 0
|
#define O_RDONLY 0
|
||||||
#define PROT_NONE 0
|
#define PROT_NONE 0
|
||||||
#define PROT_READ 1
|
#define PROT_READ 1
|
||||||
#define PROT_WRITE 2
|
#define PROT_WRITE 2
|
||||||
#define PROT_EXEC 4
|
#define PROT_EXEC 4
|
||||||
#define MAP_SHARED 1
|
#define MAP_SHARED 1
|
||||||
#define MAP_PRIVATE 2
|
#define MAP_PRIVATE 2
|
||||||
#define MAP_FIXED 16
|
#define MAP_FIXED 16
|
||||||
#define MAP_ANONYMOUS (IsLinux() ? 32 : 4096)
|
#define MAP_ANONYMOUS (IsLinux() ? 32 : 4096)
|
||||||
#define MAP_NORESERVE (IsLinux() ? 16384 : 0)
|
#define MAP_NORESERVE (IsLinux() ? 16384 : 0)
|
||||||
#define ELFCLASS32 1
|
#define ELFCLASS32 1
|
||||||
#define ELFDATA2LSB 1
|
#define ELFDATA2LSB 1
|
||||||
#define EM_NEXGEN32E 62
|
#define EM_NEXGEN32E 62
|
||||||
#define EM_AARCH64 183
|
#define EM_AARCH64 183
|
||||||
#define ET_EXEC 2
|
#define ET_EXEC 2
|
||||||
#define ET_DYN 3
|
#define ET_DYN 3
|
||||||
#define PT_LOAD 1
|
#define PT_LOAD 1
|
||||||
#define PT_DYNAMIC 2
|
#define PT_DYNAMIC 2
|
||||||
#define PT_INTERP 3
|
#define PT_INTERP 3
|
||||||
#define EI_CLASS 4
|
#define EI_CLASS 4
|
||||||
#define EI_DATA 5
|
#define EI_DATA 5
|
||||||
#define PF_X 1
|
#define PF_X 1
|
||||||
#define PF_W 2
|
#define PF_W 2
|
||||||
#define PF_R 4
|
#define PF_R 4
|
||||||
#define AT_PHDR 3
|
#define AT_PHDR 3
|
||||||
#define AT_PHENT 4
|
#define AT_PHENT 4
|
||||||
#define AT_PHNUM 5
|
#define AT_PHNUM 5
|
||||||
#define AT_PAGESZ 6
|
#define AT_PAGESZ 6
|
||||||
#define AT_EXECFN_LINUX 31
|
#define AT_FLAGS 8
|
||||||
#define AT_EXECFN_NETBSD 2014
|
#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
|
||||||
#define X_OK 1
|
#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
|
||||||
#define XCR0_SSE 2
|
#define AT_EXECFN_LINUX 31
|
||||||
#define XCR0_AVX 4
|
#define AT_EXECFN_NETBSD 2014
|
||||||
#define PR_SET_MM 35
|
#define X_OK 1
|
||||||
#define PR_SET_MM_EXE_FILE 13
|
#define XCR0_SSE 2
|
||||||
|
#define XCR0_AVX 4
|
||||||
|
#define PR_SET_MM 35
|
||||||
|
#define PR_SET_MM_EXE_FILE 13
|
||||||
|
|
||||||
#define READ32(S) \
|
#define READ32(S) \
|
||||||
((unsigned)(255 & (S)[3]) << 030 | (unsigned)(255 & (S)[2]) << 020 | \
|
((unsigned)(255 & (S)[3]) << 030 | (unsigned)(255 & (S)[2]) << 020 | \
|
||||||
|
@ -212,17 +217,18 @@ struct PathSearcher {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *syspath;
|
const char *syspath;
|
||||||
unsigned long namelen;
|
unsigned long namelen;
|
||||||
char path[1024];
|
char path[PATH_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ApeLoader {
|
struct ApeLoader {
|
||||||
union ElfPhdrBuf phdr;
|
union ElfPhdrBuf phdr;
|
||||||
struct PathSearcher ps;
|
struct PathSearcher ps;
|
||||||
char path[1024];
|
char path[PATH_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
EXTERN_C long SystemCall(long, long, long, long, long, long, long, int);
|
EXTERN_C long SystemCall(long, long, long, long, long, long, long, int);
|
||||||
EXTERN_C void Launch(void *, long, void *, int) __attribute__((__noreturn__));
|
EXTERN_C void Launch(void *, long, void *, int, void *)
|
||||||
|
__attribute__((__noreturn__));
|
||||||
|
|
||||||
extern char __executable_start[];
|
extern char __executable_start[];
|
||||||
extern char _end[];
|
extern char _end[];
|
||||||
|
@ -239,12 +245,13 @@ static int StrCmp(const char *l, const char *r) {
|
||||||
return (l[i] & 255) - (r[i] & 255);
|
return (l[i] & 255) - (r[i] & 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *BaseName(const char *s) {
|
#if 0
|
||||||
int c;
|
|
||||||
const char *b = "";
|
static const char *StrRChr(const char *s, int c) {
|
||||||
|
const char *b = 0;
|
||||||
if (s) {
|
if (s) {
|
||||||
while ((c = *s++)) {
|
for (; *s; ++s) {
|
||||||
if (c == '/') {
|
if (*s == c) {
|
||||||
b = s;
|
b = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,6 +259,13 @@ static const char *BaseName(const char *s) {
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *BaseName(const char *s) {
|
||||||
|
const char *b = StrRChr(s, '/');
|
||||||
|
return b ? b + 1 : s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void Bzero(void *a, unsigned long n) {
|
static void Bzero(void *a, unsigned long n) {
|
||||||
long z;
|
long z;
|
||||||
char *p, *e;
|
char *p, *e;
|
||||||
|
@ -343,7 +357,7 @@ static char *Utox(char p[19], unsigned long x) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *Utoa(char p[21], unsigned long x) {
|
static char *Utoa(char p[20], unsigned long x) {
|
||||||
char t;
|
char t;
|
||||||
unsigned long i, a, b;
|
unsigned long i, a, b;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -561,45 +575,22 @@ static char SearchPath(struct PathSearcher *ps) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char FindCommand(struct PathSearcher *ps) {
|
static char *Commandv(struct PathSearcher *ps, int os, char *name,
|
||||||
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.com arg1 arg2
|
|
||||||
unless $PATH has an empty string entry, e.g.
|
|
||||||
$ expert PATH=":/bin"
|
|
||||||
$ ape foo.com arg1 arg2
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* otherwise search for name on $PATH */
|
|
||||||
return SearchPath(ps);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *Commandv(struct PathSearcher *ps, int os, const char *name,
|
|
||||||
const char *syspath) {
|
const char *syspath) {
|
||||||
|
if (!(ps->namelen = StrLen((ps->name = name)))) return 0;
|
||||||
|
if (ps->literally || MemChr(ps->name, '/', ps->namelen)) return name;
|
||||||
ps->os = os;
|
ps->os = os;
|
||||||
ps->syspath = syspath ? syspath : "/bin:/usr/local/bin:/usr/bin";
|
ps->syspath = syspath ? syspath : "/bin:/usr/local/bin:/usr/bin";
|
||||||
if (!(ps->namelen = StrLen((ps->name = name)))) return 0;
|
|
||||||
if (ps->namelen + 1 > sizeof(ps->path)) return 0;
|
if (ps->namelen + 1 > sizeof(ps->path)) return 0;
|
||||||
if (FindCommand(ps)) {
|
ps->path[0] = 0;
|
||||||
|
if (SearchPath(ps)) {
|
||||||
return ps->path;
|
return ps->path;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((__noreturn__)) static void Spawn(int os, const char *exe, int fd,
|
__attribute__((__noreturn__)) static void Spawn(int os, char *exe, int fd,
|
||||||
long *sp, unsigned long pagesz,
|
long *sp, unsigned long pagesz,
|
||||||
struct ElfEhdr *e,
|
struct ElfEhdr *e,
|
||||||
struct ElfPhdr *p) {
|
struct ElfPhdr *p) {
|
||||||
|
@ -757,11 +748,11 @@ __attribute__((__noreturn__)) static void Spawn(int os, const char *exe, int fd,
|
||||||
Msyscall(dynbase + code, codesize, os);
|
Msyscall(dynbase + code, codesize, os);
|
||||||
|
|
||||||
/* call program entrypoint */
|
/* call program entrypoint */
|
||||||
Launch(IsFreebsd() ? sp : 0, dynbase + e->e_entry, sp, os);
|
Launch(IsFreebsd() ? sp : 0, dynbase + e->e_entry, exe, os, sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
|
static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
|
||||||
const char *exe, int fd, long *sp, long *auxv,
|
char *exe, int fd, long *sp, long *auxv,
|
||||||
unsigned long pagesz, int os) {
|
unsigned long pagesz, int os) {
|
||||||
long i, rc;
|
long i, rc;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
@ -885,18 +876,13 @@ __attribute__((__noreturn__)) static void ShowUsage(int os, int fd, int rc) {
|
||||||
"NAME\n"
|
"NAME\n"
|
||||||
"\n"
|
"\n"
|
||||||
" actually portable executable loader version " APE_VERSION_STR "\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"
|
" https://justine.lol/ape.html\n"
|
||||||
"\n"
|
"\n"
|
||||||
"USAGE\n"
|
"USAGE\n"
|
||||||
"\n"
|
"\n"
|
||||||
" ape [FLAGS] PROG [ARGV1,ARGV2,...]\n"
|
" ape PROG [ARGV1,ARGV2,...]\n"
|
||||||
" ape [FLAGS] - PROG [ARGV0,ARGV1,...]\n"
|
" ape - PROG [ARGV0,ARGV1,...]\n"
|
||||||
"\n"
|
|
||||||
"FLAGS\n"
|
|
||||||
"\n"
|
|
||||||
" -h show this help\n"
|
|
||||||
" -f force loading of program (do not use execve)\n"
|
|
||||||
"\n",
|
"\n",
|
||||||
0l);
|
0l);
|
||||||
Exit(rc, os);
|
Exit(rc, os);
|
||||||
|
@ -906,10 +892,10 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
|
||||||
char dl) {
|
char dl) {
|
||||||
int rc, n;
|
int rc, n;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
char literally;
|
|
||||||
const char *ape;
|
const char *ape;
|
||||||
int c, fd, os, argc;
|
int c, fd, os, argc;
|
||||||
struct ApeLoader *M;
|
struct ApeLoader *M;
|
||||||
|
char arg0, literally;
|
||||||
unsigned long pagesz;
|
unsigned long pagesz;
|
||||||
union ElfEhdrBuf *ebuf;
|
union ElfEhdrBuf *ebuf;
|
||||||
long *auxv, *ap, *endp, *sp2;
|
long *auxv, *ap, *endp, *sp2;
|
||||||
|
@ -954,11 +940,15 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
|
||||||
|
|
||||||
/* detect netbsd and find end of words */
|
/* detect netbsd and find end of words */
|
||||||
pagesz = 0;
|
pagesz = 0;
|
||||||
|
arg0 = 0;
|
||||||
for (ap = auxv; ap[0]; ap += 2) {
|
for (ap = auxv; ap[0]; ap += 2) {
|
||||||
if (ap[0] == AT_PAGESZ) {
|
if (ap[0] == AT_PAGESZ) {
|
||||||
pagesz = ap[1];
|
pagesz = ap[1];
|
||||||
} else if (SupportsNetbsd() && !os && ap[0] == AT_EXECFN_NETBSD) {
|
} else if (SupportsNetbsd() && !os && ap[0] == AT_EXECFN_NETBSD) {
|
||||||
os = 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pagesz) {
|
if (!pagesz) {
|
||||||
|
@ -971,22 +961,13 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
|
||||||
os = LINUX;
|
os = LINUX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse flags */
|
|
||||||
while (argc > 1) {
|
|
||||||
if (argv[1][0] != '-') break; /* normal argument */
|
|
||||||
if (!argv[1][1]) break; /* hyphen argument */
|
|
||||||
if (!StrCmp(argv[1], "-h") || !StrCmp(argv[1], "--help")) {
|
|
||||||
ShowUsage(os, 1, 0);
|
|
||||||
} else {
|
|
||||||
Print(os, 2, ape, ": invalid flag (pass -h for help)\n", 0l);
|
|
||||||
Exit(1, os);
|
|
||||||
}
|
|
||||||
*++sp = --argc;
|
|
||||||
++argv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we can load via shell, shebang, or binfmt_misc */
|
/* we can load via shell, shebang, or binfmt_misc */
|
||||||
if ((literally = argc >= 3 && !StrCmp(argv[1], "-"))) {
|
if (arg0) {
|
||||||
|
literally = 1;
|
||||||
|
prog = (char *)sp[2];
|
||||||
|
argc = sp[2] = sp[0] - 2;
|
||||||
|
argv = (char **)((sp += 2) + 1);
|
||||||
|
} else if ((literally = argc >= 3 && !StrCmp(argv[1], "-"))) {
|
||||||
/* if the first argument is a hyphen then we give the user the
|
/* if the first argument is a hyphen then we give the user the
|
||||||
power to change argv[0] or omit it entirely. most operating
|
power to change argv[0] or omit it entirely. most operating
|
||||||
systems don't permit the omission of argv[0] but we do, b/c
|
systems don't permit the omission of argv[0] but we do, b/c
|
||||||
|
@ -995,9 +976,13 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
|
||||||
argc = sp[3] = sp[0] - 3;
|
argc = sp[3] = sp[0] - 3;
|
||||||
argv = (char **)((sp += 3) + 1);
|
argv = (char **)((sp += 3) + 1);
|
||||||
} else if (argc < 2) {
|
} else if (argc < 2) {
|
||||||
Print(os, 2, ape, ": missing command name (pass -h for help)\n", 0l);
|
ShowUsage(os, 2, 1);
|
||||||
Exit(1, os);
|
|
||||||
} else {
|
} else {
|
||||||
|
if (argv[1][0] == '-') {
|
||||||
|
rc = !((argv[1][1] == 'h' && !argv[1][2]) ||
|
||||||
|
!StrCmp(argv[1] + 1, "-help"));
|
||||||
|
ShowUsage(os, 1 + rc, rc);
|
||||||
|
}
|
||||||
prog = (char *)sp[2];
|
prog = (char *)sp[2];
|
||||||
argc = sp[1] = sp[0] - 1;
|
argc = sp[1] = sp[0] - 1;
|
||||||
argv = (char **)((sp += 1) + 1);
|
argv = (char **)((sp += 1) + 1);
|
||||||
|
@ -1042,12 +1027,6 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
|
||||||
}
|
}
|
||||||
pe = ebuf->buf + rc;
|
pe = ebuf->buf + rc;
|
||||||
|
|
||||||
/* change argv[0] to resolved path if it's ambiguous */
|
|
||||||
if (argc > 0 && ((*prog != '/' && *exe == '/' && !StrCmp(prog, argv[0])) ||
|
|
||||||
!StrCmp(BaseName(prog), argv[0]))) {
|
|
||||||
argv[0] = exe;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ape intended behavior
|
/* ape intended behavior
|
||||||
1. if ape, will scan shell script for elf printf statements
|
1. if ape, will scan shell script for elf printf statements
|
||||||
2. shell script may have multiple lines producing elf headers
|
2. shell script may have multiple lines producing elf headers
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│
|
/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│
|
||||||
│ vi: set noet sts=2 tw=2 fenc=utf-8 :vi │
|
│ vi: set et sts=2 sw=2 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
|
|
|
@ -22,119 +22,6 @@
|
||||||
#ifdef __ASSEMBLER__
|
#ifdef __ASSEMBLER__
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
/**
|
|
||||||
* @fileoverview Macros relevant to αcτµαlly pδrταblε εxεcµταblε.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Calls near (i.e. pc+pcrel<64kB) FUNCTION.
|
|
||||||
// @mode long,legacy,real
|
|
||||||
// @cost 9 bytes overhead
|
|
||||||
.macro rlcall function:req
|
|
||||||
.byte 0x50 # push %[er]ax
|
|
||||||
.byte 0xb8,0,0 # mov $?,%[e]ax
|
|
||||||
jmp 911f
|
|
||||||
.byte 0x58 # pop %[er]ax
|
|
||||||
.byte 0xe8 # call Jvds
|
|
||||||
.long \function\()-.-4
|
|
||||||
jmp 912f
|
|
||||||
911: .byte 0x58 # pop %[er]ax
|
|
||||||
.byte 0xe8 # call Jvds
|
|
||||||
.short \function\()-.-2
|
|
||||||
912:
|
|
||||||
.endm
|
|
||||||
|
|
||||||
// Loads far (i.e. <1mb) abs constexpr ADDRESS into ES:DI+EDX+RDX.
|
|
||||||
// @mode long,legacy,real
|
|
||||||
.macro movesdi address:req
|
|
||||||
.byte 0xbf # mov $0x????xxxx,%[e]di
|
|
||||||
.short \address>>4
|
|
||||||
.byte 0x8e,0xc7 # mov %di,%es
|
|
||||||
.byte 0xbf # mov $0x????xxxx,%[e]di
|
|
||||||
.short \address&0xf
|
|
||||||
jmp 297f
|
|
||||||
.byte 0xbf # mov $0x????xxxx,%edi
|
|
||||||
.long \address
|
|
||||||
297:
|
|
||||||
.endm
|
|
||||||
|
|
||||||
// Loads 16-bit CONSTEXPR into Qw-register w/ optional zero-extend.
|
|
||||||
// @mode long,legacy,real
|
|
||||||
.macro bbmov constexpr:req abcd abcd.hi:req abcd.lo:req
|
|
||||||
.ifnb \abcd
|
|
||||||
.if (\constexpr)<128 && (\constexpr)>=0
|
|
||||||
pushpop \constexpr,\abcd
|
|
||||||
.exitm
|
|
||||||
.endif
|
|
||||||
.endif
|
|
||||||
movb $(\constexpr)>>8&0xff,\abcd.hi
|
|
||||||
movb $(\constexpr)&0xff,\abcd.lo
|
|
||||||
.endm
|
|
||||||
|
|
||||||
// Compares 16-bit CONSTEXPR with Qw-register.
|
|
||||||
// @mode long,legacy,real
|
|
||||||
.macro bbcmp constexpr:req abcd.hi:req abcd.lo:req
|
|
||||||
cmpb $(\constexpr)>>8&0xff,\abcd.hi
|
|
||||||
jnz 387f
|
|
||||||
cmpb $(\constexpr)&0xff,\abcd.lo
|
|
||||||
387:
|
|
||||||
.endm
|
|
||||||
|
|
||||||
// Adds 16-bit CONSTEXPR to Qw-register.
|
|
||||||
// @mode long,legacy,real
|
|
||||||
.macro bbadd constexpr:req abcd.hi:req abcd.lo:req
|
|
||||||
addb $(\constexpr)&0xff,\abcd.lo
|
|
||||||
.if (\constexpr) != 0
|
|
||||||
adcb $(\constexpr)>>8&0xff,\abcd.hi
|
|
||||||
.endif
|
|
||||||
.endm
|
|
||||||
|
|
||||||
// Subtracts 16-bit CONSTEXPR from Qw-register.
|
|
||||||
// @mode long,legacy,real
|
|
||||||
.macro bbsub constexpr:req abcd.hi:req abcd.lo:req
|
|
||||||
subb $(\constexpr)&0xff,\abcd.lo
|
|
||||||
.if (\constexpr) != 0
|
|
||||||
sbbb $(\constexpr)>>8&0xff,\abcd.hi
|
|
||||||
.endif
|
|
||||||
.endm
|
|
||||||
|
|
||||||
// Ands Qw-register with 16-bit CONSTEXPR.
|
|
||||||
// @mode long,legacy,real
|
|
||||||
.macro bband constexpr:req abcd.hi:req abcd.lo:req
|
|
||||||
.if ((\constexpr)&0xff) != 0xff || ((\constexpr)>>8&0xff) == 0xff
|
|
||||||
andb $(\constexpr)&0xff,\abcd.lo
|
|
||||||
.endif
|
|
||||||
.if ((\constexpr)>>8&0xff) != 0xff
|
|
||||||
andb $(\constexpr)>>8&0xff,\abcd.hi
|
|
||||||
.endif
|
|
||||||
.endm
|
|
||||||
|
|
||||||
// Ors Qw-register with 16-bit CONSTEXPR.
|
|
||||||
// @mode long,legacy,real
|
|
||||||
.macro bbor constexpr:req abcd.hi:req abcd.lo:req
|
|
||||||
.if ((\constexpr)&0xff) != 0 || ((\constexpr)>>8&0xff) != 0
|
|
||||||
orb $(\constexpr)&0xff,\abcd.lo
|
|
||||||
.endif
|
|
||||||
.if ((\constexpr)>>8&0xff) != 0
|
|
||||||
orb $(\constexpr)>>8&0xff,\abcd.hi
|
|
||||||
.endif
|
|
||||||
.endm
|
|
||||||
|
|
||||||
// Performs ACTION only if in real mode.
|
|
||||||
// @mode long,legacy,real
|
|
||||||
.macro rlo clobber:req action:vararg
|
|
||||||
990: mov $0,\clobber
|
|
||||||
.if .-990b!=3
|
|
||||||
.error "bad clobber or assembler mode"
|
|
||||||
.endif
|
|
||||||
991: \action
|
|
||||||
.rept 2-(.-991b)
|
|
||||||
nop
|
|
||||||
.endr
|
|
||||||
.if .-991b!=2
|
|
||||||
.error "ACTION must be 1-2 bytes"
|
|
||||||
.endif
|
|
||||||
.endm
|
|
||||||
|
|
||||||
// Initializes real mode stack.
|
// Initializes real mode stack.
|
||||||
// The most holiest of holy code.
|
// The most holiest of holy code.
|
||||||
// @mode real
|
// @mode real
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=asm ts=8 tw=8 fenc=utf-8 :vi │
|
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=asm ts=8 tw=8 fenc=utf-8 :vi │
|
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set et ft=make ts=8 sw=8 fenc=utf-8 :vi ──────────────────────┘
|
||||||
|
|
||||||
# Default Mode
|
# Default Mode
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set et ft=make ts=8 sw=8 fenc=utf-8 :vi ──────────────────────┘
|
||||||
#
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
#
|
#
|
||||||
|
@ -53,91 +53,6 @@
|
||||||
# OVERRIDE_FOO set ~/.cosmo.mk and target-specific (use rarely)
|
# OVERRIDE_FOO set ~/.cosmo.mk and target-specific (use rarely)
|
||||||
#
|
#
|
||||||
|
|
||||||
LC_ALL = C
|
|
||||||
SOURCE_DATE_EPOCH = 0
|
|
||||||
|
|
||||||
ARFLAGS = rcsD
|
|
||||||
ZFLAGS ?=
|
|
||||||
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)
|
|
||||||
|
|
||||||
COMMA := ,
|
|
||||||
PWD := $(shell build/bootstrap/pwd.com)
|
|
||||||
|
|
||||||
IGNORE := $(shell $(MKDIR) $(TMPDIR))
|
|
||||||
|
|
||||||
ifneq ($(findstring aarch64,$(MODE)),)
|
|
||||||
ARCH = aarch64
|
|
||||||
HOSTS ?= pi silicon
|
|
||||||
else
|
|
||||||
ARCH = x86_64
|
|
||||||
HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd
|
|
||||||
endif
|
|
||||||
|
|
||||||
ZIPOBJ_FLAGS += -a$(ARCH)
|
|
||||||
|
|
||||||
ifeq ($(PREFIX),)
|
|
||||||
ifeq ($(USE_SYSTEM_TOOLCHAIN),)
|
|
||||||
ifeq ($(ARCH),x86_64)
|
|
||||||
ifneq ("$(wildcard o/third_party/gcc/bin/x86_64-linux-cosmo-*)","")
|
|
||||||
PREFIX = o/third_party/gcc/bin/x86_64-linux-cosmo-
|
|
||||||
else
|
|
||||||
IGNORE := $(shell build/bootstrap/unbundle.com)
|
|
||||||
PREFIX = o/third_party/gcc/bin/x86_64-linux-musl-
|
|
||||||
endif
|
|
||||||
endif # ($(ARCH),x86_64))
|
|
||||||
ifeq ($(ARCH),aarch64)
|
|
||||||
ifneq ("$(wildcard o/third_party/gcc/bin/aarch64-linux-cosmo-*)","")
|
|
||||||
PREFIX = o/third_party/gcc/bin/aarch64-linux-cosmo-
|
|
||||||
else
|
|
||||||
IGNORE := $(shell build/bootstrap/unbundle.com)
|
|
||||||
PREFIX = o/third_party/gcc/bin/aarch64-linux-musl-
|
|
||||||
endif
|
|
||||||
endif # ($(ARCH),aarch64)
|
|
||||||
endif # ($(USE_SYSTEM_TOOLCHAIN),)
|
|
||||||
endif # ($(PREFIX),)
|
|
||||||
|
|
||||||
AS = $(PREFIX)as
|
|
||||||
CC = $(PREFIX)gcc
|
|
||||||
CXX = $(PREFIX)g++
|
|
||||||
CXXFILT = $(PREFIX)c++filt
|
|
||||||
LD = $(PREFIX)ld.bfd
|
|
||||||
NM = $(PREFIX)nm
|
|
||||||
GCC = $(PREFIX)gcc
|
|
||||||
STRIP = $(PREFIX)strip
|
|
||||||
OBJCOPY = $(PREFIX)objcopy
|
|
||||||
OBJDUMP = $(PREFIX)objdump
|
|
||||||
ifneq ($(wildcard $(PWD)/$(PREFIX)addr2line),)
|
|
||||||
ADDR2LINE = $(PWD)/$(PREFIX)addr2line
|
|
||||||
else
|
|
||||||
ADDR2LINE = $(PREFIX)addr2line
|
|
||||||
endif
|
|
||||||
|
|
||||||
export ADDR2LINE
|
|
||||||
export LC_ALL
|
|
||||||
export MKDIR
|
|
||||||
export MODE
|
|
||||||
export SOURCE_DATE_EPOCH
|
|
||||||
export TMPDIR
|
|
||||||
|
|
||||||
ifeq ($(LANDLOCKMAKE_VERSION),)
|
ifeq ($(LANDLOCKMAKE_VERSION),)
|
||||||
TMPSAFE = $(join $(TMPDIR),$(subst /,_,$@)).tmp
|
TMPSAFE = $(join $(TMPDIR),$(subst /,_,$@)).tmp
|
||||||
else
|
else
|
||||||
|
|
101
build/download-cosmocc.sh
Executable file
101
build/download-cosmocc.sh
Executable file
|
@ -0,0 +1,101 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# cosmocc downloader script
|
||||||
|
# https://justine.lol/cosmo3/#install
|
||||||
|
# https://github.com/jart/cosmopolitan/blob/master/tool/cosmocc/README.md
|
||||||
|
|
||||||
|
# collect arguments
|
||||||
|
OUTPUT_DIR=${1:?OUTPUT_DIR}
|
||||||
|
COSMOCC_VERSION=${2:?COSMOCC_VERSION}
|
||||||
|
COSMOCC_SHA256SUM=${3:?COSMOCC_SHA256SUM}
|
||||||
|
URL1="https://github.com/jart/cosmopolitan/releases/download/${COSMOCC_VERSION}/cosmocc-${COSMOCC_VERSION}.zip"
|
||||||
|
URL2="https://cosmo.zip/pub/cosmocc/cosmocc-${COSMOCC_VERSION}.zip"
|
||||||
|
|
||||||
|
# helper function
|
||||||
|
abort() {
|
||||||
|
printf '%s\n' "download terminated." >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# exit if already downloaded
|
||||||
|
# we need it because directory timestamps work wierdly
|
||||||
|
OUTPUT_DIR=${OUTPUT_DIR%/}
|
||||||
|
if [ -d "${OUTPUT_DIR}" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# find commands we need to securely download cosmocc
|
||||||
|
if ! UNZIP=$(command -v unzip 2>/dev/null); then
|
||||||
|
printf '%s\n' "$0: fatal error: you need the unzip command" >&2
|
||||||
|
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/unzip and put it on the system path" >&2
|
||||||
|
abort
|
||||||
|
fi
|
||||||
|
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
|
||||||
|
abort
|
||||||
|
fi
|
||||||
|
if ! SHA256SUM=$(command -v "$PWD/o/build/sha256sum" 2>/dev/null); then
|
||||||
|
if ! CC=$(command -v "$CC" 2>/dev/null); then
|
||||||
|
if ! CC=$(command -v cc 2>/dev/null); then
|
||||||
|
if ! CC=$(command -v cosmocc 2>/dev/null); then
|
||||||
|
printf '%s\n' "$0: fatal error: you need to install either sha256sum, cc, or cosmocc" >&2
|
||||||
|
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/sha256sum and put it on the system path" >&2
|
||||||
|
abort
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
mkdir -p o/build || abort
|
||||||
|
SHA256SUM="$PWD/o/build/sha256sum"
|
||||||
|
printf '%s\n' "${CC} -w -O2 -o ${SHA256SUM} build/sha256sum.c" >&2
|
||||||
|
"${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
|
||||||
|
DOWNLOAD_ARGS=-O
|
||||||
|
elif CURL=$(command -v curl 2>/dev/null); then
|
||||||
|
DOWNLOAD=$CURL
|
||||||
|
DOWNLOAD_ARGS=-fLo
|
||||||
|
else
|
||||||
|
printf '%s\n' "$0: fatal error: you need to install either wget or curl" >&2
|
||||||
|
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/wget and put it on the system path" >&2
|
||||||
|
abort
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create temporary output directory
|
||||||
|
OLDPWD=$PWD
|
||||||
|
OUTPUT_TMP="${OUTPUT_DIR}.tmp.$$/"
|
||||||
|
mkdir -p "${OUTPUT_TMP}" || abort
|
||||||
|
cd "${OUTPUT_TMP}"
|
||||||
|
die() {
|
||||||
|
cd "${OLDPWD}"
|
||||||
|
rm -rf "${OUTPUT_TMP}"
|
||||||
|
abort
|
||||||
|
}
|
||||||
|
|
||||||
|
# download cosmocc toolchain
|
||||||
|
# multiple urls avoids outages and national firewalls
|
||||||
|
if ! "${DOWNLOAD}" ${DOWNLOAD_ARGS} cosmocc.zip "${URL1}"; then
|
||||||
|
rm -f cosmocc.zip
|
||||||
|
"${DOWNLOAD}" ${DOWNLOAD_ARGS} cosmocc.zip "${URL2}" || die
|
||||||
|
fi
|
||||||
|
printf '%s\n' "${COSMOCC_SHA256SUM} *cosmocc.zip" >cosmocc.zip.sha256sum
|
||||||
|
sha256sum -c cosmocc.zip.sha256sum || die
|
||||||
|
"${UNZIP}" cosmocc.zip || die
|
||||||
|
rm -f cosmocc.zip cosmocc.zip.sha256sum
|
||||||
|
|
||||||
|
# commit output directory
|
||||||
|
cd "${OLDPWD}" || die
|
||||||
|
mv "${OUTPUT_TMP}" "${OUTPUT_DIR}" || die
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set et ft=make ts=8 sw=8 fenc=utf-8 :vi ──────────────────────┘
|
||||||
#
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
#── vi: set et ft=sh ts=2 sts=2 fenc=utf-8 :vi ─────────────┘
|
||||||
#
|
#
|
||||||
# OVERVIEW
|
# OVERVIEW
|
||||||
#
|
#
|
||||||
|
@ -66,7 +66,7 @@ set -- --regex-c='/^extern [^(]*(\*const \([^)]*\))(/\1/b' "$@"
|
||||||
# struct WorstSoftwareEver;
|
# struct WorstSoftwareEver;
|
||||||
set -- --regex-c='/^struct.*;$/uehocruehcroue/b' "$@"
|
set -- --regex-c='/^struct.*;$/uehocruehcroue/b' "$@"
|
||||||
|
|
||||||
exec $TAGS \
|
build/run $TAGS \
|
||||||
-e \
|
-e \
|
||||||
--langmap=c:.c.h \
|
--langmap=c:.c.h \
|
||||||
--exclude=libc/nt/struct/imagefileheader.internal.h \
|
--exclude=libc/nt/struct/imagefileheader.internal.h \
|
||||||
|
|
|
@ -6,14 +6,14 @@ if [ -n "$OBJDUMP" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
find_objdump() {
|
find_objdump() {
|
||||||
if [ -x o/third_party/gcc/bin/$1-linux-cosmo-objdump ]; then
|
if [ -x .cosmocc/3.2/bin/$1-linux-cosmo-objdump ]; then
|
||||||
OBJDUMP=o/third_party/gcc/bin/$1-linux-cosmo-objdump
|
OBJDUMP=.cosmocc/3.2/bin/$1-linux-cosmo-objdump
|
||||||
elif [ -x o/third_party/gcc/bin/$1-linux-musl-objdump ]; then
|
elif [ -x .cosmocc/3.2/bin/$1-linux-musl-objdump ]; then
|
||||||
OBJDUMP=o/third_party/gcc/bin/$1-linux-musl-objdump
|
OBJDUMP=.cosmocc/3.2/bin/$1-linux-musl-objdump
|
||||||
elif [ -x "$COSMO/o/third_party/gcc/bin/$1-linux-cosmo-objdump" ]; then
|
elif [ -x "$COSMO/.cosmocc/3.2/bin/$1-linux-cosmo-objdump" ]; then
|
||||||
OBJDUMP="$COSMO/o/third_party/gcc/bin/$1-linux-cosmo-objdump"
|
OBJDUMP="$COSMO/.cosmocc/3.2/bin/$1-linux-cosmo-objdump"
|
||||||
elif [ -x "$COSMO/o/third_party/gcc/bin/$1-linux-musl-objdump" ]; then
|
elif [ -x "$COSMO/.cosmocc/3.2/bin/$1-linux-musl-objdump" ]; then
|
||||||
OBJDUMP="$COSMO/o/third_party/gcc/bin/$1-linux-musl-objdump"
|
OBJDUMP="$COSMO/.cosmocc/3.2/bin/$1-linux-musl-objdump"
|
||||||
else
|
else
|
||||||
echo "error: toolchain not found (try running 'cosmocc --update' or 'make' in the cosmo monorepo)" >&2
|
echo "error: toolchain not found (try running 'cosmocc --update' or 'make' in the cosmo monorepo)" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set et ft=make ts=8 sw=8 fenc=utf-8 :vi ──────────────────────┘
|
||||||
#
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:sed;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:sed;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: et ft=sed ts=8 tw=8 fenc=utf-8 :vi─────────────────┘
|
#── vi: et ft=sed ts=8 sw=8 fenc=utf-8 :vi ────────────────┘
|
||||||
#
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set et ft=make ts=8 sw=8 fenc=utf-8 :vi ──────────────────────┘
|
||||||
#
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
#
|
#
|
||||||
|
@ -40,6 +40,9 @@ o/$(MODE)/%.h: %.c
|
||||||
o/$(MODE)/%.o: %.cc
|
o/$(MODE)/%.o: %.cc
|
||||||
@$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
@$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
||||||
|
|
||||||
|
o/$(MODE)/%.o: %.cpp
|
||||||
|
@$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
||||||
|
|
||||||
o/$(MODE)/%.lds: %.lds
|
o/$(MODE)/%.lds: %.lds
|
||||||
@$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
|
@$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
if printf '%s\n' "$*" | grep aarch64 >/dev/null 2>&1; then
|
UNAMEM=$(uname -m)
|
||||||
if [ ! -f o/third_party/qemu/qemu-aarch64 ]; then
|
UNAMES=$(uname -s)
|
||||||
make -j8 o/third_party/qemu/qemu-aarch64
|
if [ x"$UNAMES" = x"Darwin" ] && [ x"$UNAMEM" = x"arm64" ]; then
|
||||||
fi
|
exec ape "$@"
|
||||||
exec o/third_party/qemu/qemu-aarch64 "$@"
|
|
||||||
else
|
else
|
||||||
exec "$@"
|
exec "$@"
|
||||||
fi
|
fi
|
||||||
|
|
443
build/sha256sum.c
Normal file
443
build/sha256sum.c
Normal file
|
@ -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,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
|
|
||||||
.PHONY: o/$(MODE)/dsp
|
.PHONY: o/$(MODE)/dsp
|
||||||
o/$(MODE)/dsp: o/$(MODE)/dsp/core \
|
o/$(MODE)/dsp: o/$(MODE)/dsp/core \
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set et ft=make ts=8 sw=8 fenc=utf-8 :vi ──────────────────────┘
|
||||||
|
|
||||||
PKGS += DSP_BMP
|
PKGS += DSP_BMP
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
|
|
||||||
PKGS += DSP_CORE
|
PKGS += DSP_CORE
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,9 @@ int mulaw(int);
|
||||||
int unmulaw(int);
|
int unmulaw(int);
|
||||||
void *double2byte(long, const void *, double, double) vallocesque;
|
void *double2byte(long, const void *, double, double) vallocesque;
|
||||||
void *byte2double(long, const void *, double, double) vallocesque;
|
void *byte2double(long, const void *, double, double) vallocesque;
|
||||||
void *dct(float[8][8], float, float, float, float, float);
|
void *dct(float[restrict hasatleast 8][8], unsigned,
|
||||||
void *dctjpeg(float[8][8]);
|
float, float, float, float, float);
|
||||||
|
void *dctjpeg(float[restrict hasatleast 8][8], unsigned);
|
||||||
double det3(const double[3][3]) nosideeffect;
|
double det3(const double[3][3]) nosideeffect;
|
||||||
void *inv3(double[restrict 3][3], const double[restrict 3][3], double);
|
void *inv3(double[restrict 3][3], const double[restrict 3][3], double);
|
||||||
void *matmul3(double[restrict 3][3], const double[3][3], const double[3][3]);
|
void *matmul3(double[restrict 3][3], const double[3][3], const double[3][3]);
|
||||||
|
|
|
@ -18,40 +18,40 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "dsp/core/core.h"
|
#include "dsp/core/core.h"
|
||||||
|
|
||||||
#define DCT(A, B, C, D, E, F, G, H, T, C0, C1, C2, C3, C4) \
|
#define DCT(A, B, C, D, E, F, G, H, T, C0, C1, C2, C3, C4) \
|
||||||
do { \
|
do { \
|
||||||
T z1, z2, z3, z4, z5, z11, z13; \
|
T z1, z2, z3, z4, z5, z11, z13; \
|
||||||
T t0, t1, t2, t3, t4, t5, t6, t7, t10, t11, t12, t13; \
|
T t0, t1, t2, t3, t4, t5, t6, t7, t10, t11, t12, t13; \
|
||||||
t0 = A + H; \
|
t0 = A + H; \
|
||||||
t7 = A - H; \
|
t7 = A - H; \
|
||||||
t1 = B + G; \
|
t1 = B + G; \
|
||||||
t6 = B - G; \
|
t6 = B - G; \
|
||||||
t2 = C + F; \
|
t2 = C + F; \
|
||||||
t5 = C - F; \
|
t5 = C - F; \
|
||||||
t3 = D + E; \
|
t3 = D + E; \
|
||||||
t4 = D - E; \
|
t4 = D - E; \
|
||||||
t10 = t0 + t3; \
|
t10 = t0 + t3; \
|
||||||
t13 = t0 - t3; \
|
t13 = t0 - t3; \
|
||||||
t11 = t1 + t2; \
|
t11 = t1 + t2; \
|
||||||
t12 = t1 - t2; \
|
t12 = t1 - t2; \
|
||||||
A = t10 + t11; \
|
A = t10 + t11; \
|
||||||
E = t10 - t11; \
|
E = t10 - t11; \
|
||||||
z1 = (t12 + t13) * C0; \
|
z1 = (t12 + t13) * C0; \
|
||||||
C = t13 + z1; \
|
C = t13 + z1; \
|
||||||
G = t13 - z1; \
|
G = t13 - z1; \
|
||||||
t10 = t4 + t5; \
|
t10 = t4 + t5; \
|
||||||
t11 = t5 + t6; \
|
t11 = t5 + t6; \
|
||||||
t12 = t6 + t7; \
|
t12 = t6 + t7; \
|
||||||
z5 = (t10 - t12) * C1; \
|
z5 = (t10 - t12) * C1; \
|
||||||
z2 = t10 * C2 + z5; \
|
z2 = t10 * C2 + z5; \
|
||||||
z4 = t12 * C3 + z5; \
|
z4 = t12 * C3 + z5; \
|
||||||
z3 = t11 * C4; \
|
z3 = t11 * C4; \
|
||||||
z11 = t7 + z3; \
|
z11 = t7 + z3; \
|
||||||
z13 = t7 - z3; \
|
z13 = t7 - z3; \
|
||||||
F = z13 + z2; \
|
F = z13 + z2; \
|
||||||
D = z13 - z2; \
|
D = z13 - z2; \
|
||||||
B = z11 + z4; \
|
B = z11 + z4; \
|
||||||
H = z11 - z4; \
|
H = z11 - z4; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,20 +65,21 @@
|
||||||
*
|
*
|
||||||
* @cost ~100ns
|
* @cost ~100ns
|
||||||
*/
|
*/
|
||||||
void *dct(float M[8][8], float c0, float c1, float c2, float c3, float c4) {
|
void *dct(float M[restrict hasatleast 8][8], unsigned stride,
|
||||||
|
float c0, float c1, float c2, float c3, float c4) {
|
||||||
unsigned y, x;
|
unsigned y, x;
|
||||||
for (y = 0; y < 8; ++y) {
|
for (y = 0; y < stride * 8; y += stride) {
|
||||||
DCT(M[y][0], M[y][1], M[y][2], M[y][3], M[y][4], M[y][5], M[y][6], M[y][7],
|
DCT(M[y][0], M[y][1], M[y][2], M[y][3], M[y][4], M[y][5], M[y][6], M[y][7],
|
||||||
float, c0, c1, c2, c3, c4);
|
float, c0, c1, c2, c3, c4);
|
||||||
}
|
}
|
||||||
for (x = 0; x < 8; ++x) {
|
for (x = 0; x < stride * 8; x += stride) {
|
||||||
DCT(M[0][x], M[1][x], M[2][x], M[3][x], M[4][x], M[5][x], M[6][x], M[7][x],
|
DCT(M[0][x], M[1][x], M[2][x], M[3][x], M[4][x], M[5][x], M[6][x], M[7][x],
|
||||||
float, c0, c1, c2, c3, c4);
|
float, c0, c1, c2, c3, c4);
|
||||||
}
|
}
|
||||||
return M;
|
return M;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *dctjpeg(float M[8][8]) {
|
void *dctjpeg(float M[restrict hasatleast 8][8], unsigned stride) {
|
||||||
return dct(M, .707106781f, .382683433f, .541196100f, 1.306562965f,
|
return dct(M, stride, .707106781f, .382683433f, .541196100f, 1.306562965f,
|
||||||
.707106781f);
|
.707106781f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
|
|
||||||
PKGS += DSP_MPEG
|
PKGS += DSP_MPEG
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
#include "dsp/mpeg/mpeg.h"
|
#include "dsp/mpeg/mpeg.h"
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
struct FILE;
|
|
||||||
|
|
||||||
enum plm_buffer_mode {
|
enum plm_buffer_mode {
|
||||||
PLM_BUFFER_MODE_FILE,
|
PLM_BUFFER_MODE_FILE,
|
||||||
PLM_BUFFER_MODE_FIXED_MEM,
|
PLM_BUFFER_MODE_FIXED_MEM,
|
||||||
|
@ -17,7 +15,7 @@ typedef struct plm_buffer_t {
|
||||||
unsigned length;
|
unsigned length;
|
||||||
int free_when_done;
|
int free_when_done;
|
||||||
int close_when_done;
|
int close_when_done;
|
||||||
struct FILE *fh;
|
FILE *fh;
|
||||||
plm_buffer_load_callback load_callback;
|
plm_buffer_load_callback load_callback;
|
||||||
void *load_callback_user_data;
|
void *load_callback_user_data;
|
||||||
unsigned char *bytes;
|
unsigned char *bytes;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=asm ts=8 tw=8 fenc=utf-8 :vi │
|
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=c ts=4 sw=4 fenc=utf-8 :vi │
|
│ vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │
|
│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │
|
||||||
│ Dominic Szablewski - https://phoboslab.org │
|
│ Dominic Szablewski - https://phoboslab.org │
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=c ts=4 sw=4 fenc=utf-8 :vi │
|
│ vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │
|
│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │
|
||||||
│ Dominic Szablewski - https://phoboslab.org │
|
│ Dominic Szablewski - https://phoboslab.org │
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
#ifndef COSMOPOLITAN_DSP_MPEG_MPEG_H_
|
#ifndef COSMOPOLITAN_DSP_MPEG_MPEG_H_
|
||||||
#define COSMOPOLITAN_DSP_MPEG_MPEG_H_
|
#define COSMOPOLITAN_DSP_MPEG_MPEG_H_
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
struct FILE;
|
|
||||||
|
|
||||||
typedef struct plm_t plm_t;
|
typedef struct plm_t plm_t;
|
||||||
typedef struct plm_buffer_t plm_buffer_t;
|
typedef struct plm_buffer_t plm_buffer_t;
|
||||||
typedef struct plm_demux_t plm_demux_t;
|
typedef struct plm_demux_t plm_demux_t;
|
||||||
|
@ -112,7 +111,7 @@ plm_t *plm_create_with_filename(const char *filename);
|
||||||
* to let plmpeg call fclose() on the handle when plm_destroy() is
|
* to let plmpeg call fclose() on the handle when plm_destroy() is
|
||||||
* called.
|
* called.
|
||||||
*/
|
*/
|
||||||
plm_t *plm_create_with_file(struct FILE *fh, int close_when_done);
|
plm_t *plm_create_with_file(FILE *fh, int close_when_done);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a plmpeg instance with pointer to memory as source. This assumes the
|
* Create a plmpeg instance with pointer to memory as source. This assumes the
|
||||||
|
@ -257,7 +256,7 @@ plm_buffer_t *plm_buffer_create_with_filename(const char *filename);
|
||||||
* to let plmpeg call fclose() on the handle when plm_destroy() is
|
* to let plmpeg call fclose() on the handle when plm_destroy() is
|
||||||
* called.
|
* called.
|
||||||
*/
|
*/
|
||||||
plm_buffer_t *plm_buffer_create_with_file(struct FILE *fh, int close_when_done);
|
plm_buffer_t *plm_buffer_create_with_file(FILE *fh, int close_when_done);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a buffer instance with a pointer to memory as source. This assumes
|
* Create a buffer instance with a pointer to memory as source. This assumes
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=c ts=4 sw=4 fenc=utf-8 :vi │
|
│ vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │
|
│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │
|
||||||
│ Dominic Szablewski - https://phoboslab.org │
|
│ Dominic Szablewski - https://phoboslab.org │
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=c ts=4 sw=4 fenc=utf-8 :vi │
|
│ vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │
|
│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │
|
||||||
│ Dominic Szablewski - https://phoboslab.org │
|
│ Dominic Szablewski - https://phoboslab.org │
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
|
|
||||||
PKGS += DSP_SCALE
|
PKGS += DSP_SCALE
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/mem/gc.internal.h"
|
#include "libc/mem/gc.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
|
|
||||||
PKGS += DSP_TTY
|
PKGS += DSP_TTY
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=asm ts=8 tw=8 fenc=utf-8 :vi │
|
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "dsp/tty/tty.h"
|
#include "dsp/tty/tty.h"
|
||||||
#include "libc/mem/arraylist2.internal.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/mem/mem.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
struct FILE;
|
|
||||||
struct termios;
|
struct termios;
|
||||||
|
|
||||||
struct TtyIdent {
|
struct TtyIdent {
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "libc/calls/ucontext.h"
|
#include "libc/calls/ucontext.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/gc.internal.h"
|
#include "libc/mem/gc.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/fileno.h"
|
#include "libc/sysv/consts/fileno.h"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=asm ts=8 tw=8 fenc=utf-8 :vi │
|
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=asm ts=8 tw=8 fenc=utf-8 :vi │
|
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
|
|
||||||
PKGS += EXAMPLES
|
PKGS += EXAMPLES
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ EXAMPLES_DIRECTDEPS = \
|
||||||
DSP_TTY \
|
DSP_TTY \
|
||||||
LIBC_CALLS \
|
LIBC_CALLS \
|
||||||
LIBC_DLOPEN \
|
LIBC_DLOPEN \
|
||||||
LIBC_DNS \
|
|
||||||
LIBC_FMT \
|
LIBC_FMT \
|
||||||
LIBC_INTRIN \
|
LIBC_INTRIN \
|
||||||
LIBC_IRQ \
|
LIBC_IRQ \
|
||||||
|
@ -86,7 +85,6 @@ EXAMPLES_DIRECTDEPS = \
|
||||||
THIRD_PARTY_MUSL \
|
THIRD_PARTY_MUSL \
|
||||||
THIRD_PARTY_NSYNC \
|
THIRD_PARTY_NSYNC \
|
||||||
THIRD_PARTY_NSYNC_MEM \
|
THIRD_PARTY_NSYNC_MEM \
|
||||||
THIRD_PARTY_QUICKJS \
|
|
||||||
THIRD_PARTY_SED \
|
THIRD_PARTY_SED \
|
||||||
THIRD_PARTY_STB \
|
THIRD_PARTY_STB \
|
||||||
THIRD_PARTY_TR \
|
THIRD_PARTY_TR \
|
||||||
|
@ -154,7 +152,6 @@ o/$(MODE)/examples/picol.com.dbg: \
|
||||||
$(APE_NO_MODIFY_SELF)
|
$(APE_NO_MODIFY_SELF)
|
||||||
@$(APELINK)
|
@$(APELINK)
|
||||||
|
|
||||||
o/$(MODE)/examples/nesemu1.o: private QUOTA += -M512m
|
|
||||||
o/$(MODE)/usr/share/dict/words.zip.o: private ZIPOBJ_FLAGS += -C2
|
o/$(MODE)/usr/share/dict/words.zip.o: private ZIPOBJ_FLAGS += -C2
|
||||||
|
|
||||||
$(EXAMPLES_OBJS): examples/BUILD.mk
|
$(EXAMPLES_OBJS): examples/BUILD.mk
|
||||||
|
|
23
examples/crashreport2.cc
Normal file
23
examples/crashreport2.cc
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#if 0
|
||||||
|
/*─────────────────────────────────────────────────────────────────╗
|
||||||
|
│ To the extent possible under law, Justine Tunney has waived │
|
||||||
|
│ all copyright and related or neighboring rights to this file, │
|
||||||
|
│ as it is written in the following disclaimers: │
|
||||||
|
│ • http://unlicense.org/ │
|
||||||
|
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────*/
|
||||||
|
#endif
|
||||||
|
#include "libc/math.h"
|
||||||
|
#include "libc/runtime/runtime.h"
|
||||||
|
|
||||||
|
void crash(long x0, long x1, long x2, //
|
||||||
|
double v0, double v1, double v2) {
|
||||||
|
__builtin_trap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void (*pCrash)(long, long, long, double, double, double) = crash;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
ShowCrashReports();
|
||||||
|
pCrash(1, 2, 3, NAN, NAN, NAN);
|
||||||
|
}
|
|
@ -2,9 +2,9 @@
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
printf("%s\n", argv[0]);
|
fprintf(stderr, "%s (%s)\n", argv[0], GetProgramExecutableName());
|
||||||
for (char **p = environ; *p; ++p) {
|
for (char **p = environ; *p; ++p) {
|
||||||
printf(" %s\n", *p);
|
printf("%s\n", *p);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,7 +285,7 @@ int main(int argc, char *argv[]) {
|
||||||
// print all the ips that 0.0.0.0 would bind
|
// print all the ips that 0.0.0.0 would bind
|
||||||
// Cosmo's GetHostIps() API is much easier than ioctl(SIOCGIFCONF)
|
// Cosmo's GetHostIps() API is much easier than ioctl(SIOCGIFCONF)
|
||||||
uint32_t *hostips;
|
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,
|
kprintf("listening on http://%hhu.%hhu.%hhu.%hhu:%hu\n", hostips[i] >> 24,
|
||||||
hostips[i] >> 16, hostips[i] >> 8, hostips[i], PORT);
|
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_setguardsize(&attr, pagesz));
|
||||||
unassert(!pthread_attr_setsigmask_np(&attr, &block));
|
unassert(!pthread_attr_setsigmask_np(&attr, &block));
|
||||||
unassert(!pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0));
|
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) {
|
for (i = 0; i < threads; ++i) {
|
||||||
int rc;
|
int rc;
|
||||||
++a_workers;
|
++a_workers;
|
||||||
|
|
|
@ -50,7 +50,7 @@ void List(const char *path) {
|
||||||
if (strcmp(path, ".") == 0) {
|
if (strcmp(path, ".") == 0) {
|
||||||
vpath = "";
|
vpath = "";
|
||||||
} else if (!endswith(path, "/")) {
|
} else if (!endswith(path, "/")) {
|
||||||
vpath = _gc(xasprintf("%s/", path));
|
vpath = gc(xasprintf("%s/", path));
|
||||||
} else {
|
} else {
|
||||||
vpath = path;
|
vpath = path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
╚─────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────*/
|
||||||
#endif
|
#endif
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/dns/dns.h"
|
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
@ -26,6 +25,7 @@
|
||||||
#include "libc/sysv/consts/sock.h"
|
#include "libc/sysv/consts/sock.h"
|
||||||
#include "libc/sysv/consts/sol.h"
|
#include "libc/sysv/consts/sol.h"
|
||||||
#include "third_party/getopt/getopt.internal.h"
|
#include "third_party/getopt/getopt.internal.h"
|
||||||
|
#include "third_party/musl/netdb.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fileoverview netcat clone
|
* @fileoverview netcat clone
|
||||||
|
@ -60,9 +60,7 @@ int main(int argc, char *argv[]) {
|
||||||
halfclose = false;
|
halfclose = false;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
fputs("Usage: ", stdout);
|
tinyprint(1, "Usage: ", argv[0], " [-hH] IP PORT\n", NULL);
|
||||||
fputs(argv[0], stdout);
|
|
||||||
fputs(" [-hH] IP PORT\n", stdout);
|
|
||||||
exit(0);
|
exit(0);
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "bad option %d\n", opt);
|
fprintf(stderr, "bad option %d\n", opt);
|
||||||
|
@ -76,17 +74,9 @@ int main(int argc, char *argv[]) {
|
||||||
host = argv[optind + 0];
|
host = argv[optind + 0];
|
||||||
port = argv[optind + 1];
|
port = argv[optind + 1];
|
||||||
|
|
||||||
switch ((rc = getaddrinfo(host, port, &hint, &ai))) {
|
if ((rc = getaddrinfo(host, port, &hint, &ai))) {
|
||||||
case EAI_SUCCESS:
|
tinyprint(2, host, ": ", gai_strerror(rc), "\n", NULL);
|
||||||
break;
|
exit(1);
|
||||||
case EAI_SYSTEM:
|
|
||||||
perror("getaddrinfo");
|
|
||||||
exit(1);
|
|
||||||
default:
|
|
||||||
fputs("EAI_", stderr);
|
|
||||||
fputs(gai_strerror(rc), stderr);
|
|
||||||
fputs("\n", stderr);
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1) {
|
if ((sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1) {
|
||||||
|
@ -95,12 +85,12 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) == -1) {
|
if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) == -1) {
|
||||||
perror("setsockopt(SO_LINGER)");
|
perror("SO_LINGER");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
|
if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
|
||||||
perror("connect");
|
perror(host);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
#
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
#
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
#
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
#
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright (c) 2010, 2012 David E. O'Brien │
|
│ Copyright (c) 2010, 2012 David E. O'Brien │
|
||||||
│ Copyright (c) 1980, 1992, 1993 │
|
│ Copyright (c) 1980, 1992, 1993 │
|
||||||
|
|
|
@ -80,10 +80,10 @@ void PrintFileMetadata(const char *pathname, struct stat *st) {
|
||||||
DescribeFileType(st->st_mode), "owner id", st->st_uid, "group id",
|
DescribeFileType(st->st_mode), "owner id", st->st_uid, "group id",
|
||||||
st->st_gid, "flags", st->st_flags, "gen", st->st_gen,
|
st->st_gid, "flags", st->st_flags, "gen", st->st_gen,
|
||||||
"device id (if special)", st->st_rdev, "block size", st->st_blksize,
|
"device id (if special)", st->st_rdev, "block size", st->st_blksize,
|
||||||
"access time", _gc(xiso8601(&st->st_atim)), "modified time",
|
"access time", gc(xiso8601(&st->st_atim)), "modified time",
|
||||||
_gc(xiso8601(&st->st_mtim)), "c[omplicated]time",
|
gc(xiso8601(&st->st_mtim)), "c[omplicated]time",
|
||||||
_gc(xiso8601(&st->st_ctim)), "birthtime",
|
gc(xiso8601(&st->st_ctim)), "birthtime",
|
||||||
_gc(xiso8601(&st->st_birthtim)));
|
gc(xiso8601(&st->st_birthtim)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
|
@ -128,7 +128,7 @@
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/alg.h"
|
#include "libc/mem/alg.h"
|
||||||
#include "libc/mem/alloca.h"
|
#include "libc/mem/alloca.h"
|
||||||
#include "libc/mem/gc.internal.h"
|
#include "libc/mem/gc.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/paths.h"
|
#include "libc/paths.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
@ -157,14 +157,14 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The follow should be set to reflect the type of system you have:
|
* The follow should be set to reflect the type of system you have:
|
||||||
* JOBS -> 1 if you have Berkeley job control, 0 otherwise.
|
* JOBS -> 1 if you have Berkeley job control, 0 otherwise.
|
||||||
* SHORTNAMES -> 1 if your linker cannot handle long names.
|
* SHORTNAMES -> 1 if your linker cannot handle long names.
|
||||||
* define BSD if you are running 4.2 BSD or later.
|
* define BSD if you are running 4.2 BSD or later.
|
||||||
* define SYSV if you are running under System V.
|
* define SYSV if you are running under System V.
|
||||||
* define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
|
* define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
|
||||||
* define DEBUG=2 to compile in and turn on debugging.
|
* define DEBUG=2 to compile in and turn on debugging.
|
||||||
* define DO_SHAREDVFORK to indicate that vfork(2) shares its address
|
* define DO_SHAREDVFORK to indicate that vfork(2) shares its address
|
||||||
* with its parent.
|
* with its parent.
|
||||||
*
|
*
|
||||||
* When debugging is on, debugging info will be written to ./trace and
|
* When debugging is on, debugging info will be written to ./trace and
|
||||||
* a quit signal will generate a core dump.
|
* a quit signal will generate a core dump.
|
||||||
|
@ -6604,10 +6604,10 @@ static struct job *growjobtab(void) {
|
||||||
* own process group. Jp is a job structure that the job is to be added to.
|
* own process group. Jp is a job structure that the job is to be added to.
|
||||||
* N is the command that will be evaluated by the child. Both jp and n may
|
* N is the command that will be evaluated by the child. Both jp and n may
|
||||||
* be NULL. The mode parameter can be one of the following:
|
* be NULL. The mode parameter can be one of the following:
|
||||||
* FORK_FG - Fork off a foreground process.
|
* FORK_FG - Fork off a foreground process.
|
||||||
* FORK_BG - Fork off a background process.
|
* FORK_BG - Fork off a background process.
|
||||||
* FORK_NOJOB - Like FORK_FG, but don't give the process its own
|
* FORK_NOJOB - Like FORK_FG, but don't give the process its own
|
||||||
* process group even if job control is on.
|
* process group even if job control is on.
|
||||||
*
|
*
|
||||||
* When job control is turned off, background processes have their standard
|
* When job control is turned off, background processes have their standard
|
||||||
* input redirected to /dev/null (except for the second and later processes
|
* input redirected to /dev/null (except for the second and later processes
|
||||||
|
@ -8403,10 +8403,10 @@ static void nlnoprompt(void) {
|
||||||
/*
|
/*
|
||||||
* Read the next input token.
|
* Read the next input token.
|
||||||
* If the token is a word, we set backquotelist to the list of cmds in
|
* If the token is a word, we set backquotelist to the list of cmds in
|
||||||
* backquotes. We set quoteflag to true if any part of the word was
|
* backquotes. We set quoteflag to true if any part of the word was
|
||||||
* quoted.
|
* quoted.
|
||||||
* If the token is TREDIR, then we set redirnode to a structure containing
|
* If the token is TREDIR, then we set redirnode to a structure containing
|
||||||
* the redirection.
|
* the redirection.
|
||||||
*
|
*
|
||||||
* [Change comment: here documents and internal procedures]
|
* [Change comment: here documents and internal procedures]
|
||||||
* [Readtoken shouldn't have any arguments. Perhaps we should make the
|
* [Readtoken shouldn't have any arguments. Perhaps we should make the
|
||||||
|
@ -9767,7 +9767,7 @@ out:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print SysV echo(1) style escape string
|
* Print SysV echo(1) style escape string
|
||||||
* Halts processing string if a \c escape is encountered.
|
* Halts processing string if a \c escape is encountered.
|
||||||
*/
|
*/
|
||||||
static int conv_escape_str(char *str, char **sp) {
|
static int conv_escape_str(char *str, char **sp) {
|
||||||
int c;
|
int c;
|
||||||
|
@ -9941,10 +9941,10 @@ static int echocmd(int argc, char **argv) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* test(1) accepts the following grammar:
|
/* test(1) accepts the following grammar:
|
||||||
oexpr ::= aexpr | aexpr "-o" oexpr ;
|
oexpr ::= aexpr | aexpr "-o" oexpr ;
|
||||||
aexpr ::= nexpr | nexpr "-a" aexpr ;
|
aexpr ::= nexpr | nexpr "-a" aexpr ;
|
||||||
nexpr ::= primary | "!" primary
|
nexpr ::= primary | "!" primary
|
||||||
primary ::= unary-operator operand
|
primary ::= unary-operator operand
|
||||||
| operand binary-operator operand
|
| operand binary-operator operand
|
||||||
| operand
|
| operand
|
||||||
| "(" oexpr ")"
|
| "(" oexpr ")"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright (c) 1980, 1993 │
|
│ Copyright (c) 1980, 1993 │
|
||||||
│ The Regents of the University of California. All rights reserved. │
|
│ The Regents of the University of California. All rights reserved. │
|
||||||
|
@ -30,12 +30,13 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/weirdtypes.h"
|
#include "libc/calls/weirdtypes.h"
|
||||||
#include "libc/dns/dns.h"
|
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/log/bsd.h"
|
#include "libc/log/bsd.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
#include "libc/sock/sock.h"
|
||||||
#include "libc/sock/struct/pollfd.h"
|
#include "libc/sock/struct/pollfd.h"
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/af.h"
|
#include "libc/sysv/consts/af.h"
|
||||||
#include "libc/sysv/consts/ex.h"
|
#include "libc/sysv/consts/ex.h"
|
||||||
|
@ -44,6 +45,7 @@
|
||||||
#include "libc/sysv/consts/poll.h"
|
#include "libc/sysv/consts/poll.h"
|
||||||
#include "libc/sysv/consts/sock.h"
|
#include "libc/sysv/consts/sock.h"
|
||||||
#include "third_party/getopt/getopt.internal.h"
|
#include "third_party/getopt/getopt.internal.h"
|
||||||
|
#include "third_party/musl/netdb.h"
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
|
|
||||||
PKGS += LIBC
|
PKGS += LIBC
|
||||||
|
|
||||||
|
@ -142,6 +142,9 @@ libc/isystem/nsync_once.h \
|
||||||
libc/isystem/nsync_time.h \
|
libc/isystem/nsync_time.h \
|
||||||
libc/isystem/nsync_waiter.h \
|
libc/isystem/nsync_waiter.h \
|
||||||
libc/isystem/numeric \
|
libc/isystem/numeric \
|
||||||
|
libc/isystem/omp-tools.h \
|
||||||
|
libc/isystem/omp.h \
|
||||||
|
libc/isystem/ompx.h \
|
||||||
libc/isystem/optional \
|
libc/isystem/optional \
|
||||||
libc/isystem/ostream \
|
libc/isystem/ostream \
|
||||||
libc/isystem/paths.h \
|
libc/isystem/paths.h \
|
||||||
|
@ -164,6 +167,7 @@ libc/isystem/semaphore.h \
|
||||||
libc/isystem/set \
|
libc/isystem/set \
|
||||||
libc/isystem/setjmp.h \
|
libc/isystem/setjmp.h \
|
||||||
libc/isystem/sgxintrin.h \
|
libc/isystem/sgxintrin.h \
|
||||||
|
libc/isystem/shadow.h \
|
||||||
libc/isystem/shared_mutex \
|
libc/isystem/shared_mutex \
|
||||||
libc/isystem/signal.h \
|
libc/isystem/signal.h \
|
||||||
libc/isystem/smmintrin.h \
|
libc/isystem/smmintrin.h \
|
||||||
|
@ -250,6 +254,7 @@ libc/isystem/uio.h \
|
||||||
libc/isystem/unistd.h \
|
libc/isystem/unistd.h \
|
||||||
libc/isystem/unordered_map \
|
libc/isystem/unordered_map \
|
||||||
libc/isystem/unordered_set \
|
libc/isystem/unordered_set \
|
||||||
|
libc/isystem/unwind.h \
|
||||||
libc/isystem/utility \
|
libc/isystem/utility \
|
||||||
libc/isystem/utime.h \
|
libc/isystem/utime.h \
|
||||||
libc/isystem/utmp.h \
|
libc/isystem/utmp.h \
|
||||||
|
@ -272,11 +277,12 @@ LIBC_INCS = $(filter %.inc,$(LIBC_FILES))
|
||||||
LIBC_CHECKS = $(LIBC_HDRS_H:%=o/$(MODE)/%.ok)
|
LIBC_CHECKS = $(LIBC_HDRS_H:%=o/$(MODE)/%.ok)
|
||||||
LIBC_FILES := $(wildcard libc/*)
|
LIBC_FILES := $(wildcard libc/*)
|
||||||
|
|
||||||
|
o/$(MODE)/libc/isystem/ompx.h.ok: private CPPFLAGS += -Wno-unknown-pragmas
|
||||||
|
|
||||||
.PHONY: o/$(MODE)/libc
|
.PHONY: o/$(MODE)/libc
|
||||||
o/$(MODE)/libc: o/$(MODE)/libc/calls \
|
o/$(MODE)/libc: o/$(MODE)/libc/calls \
|
||||||
o/$(MODE)/libc/crt \
|
o/$(MODE)/libc/crt \
|
||||||
o/$(MODE)/libc/dlopen \
|
o/$(MODE)/libc/dlopen \
|
||||||
o/$(MODE)/libc/dns \
|
|
||||||
o/$(MODE)/libc/elf \
|
o/$(MODE)/libc/elf \
|
||||||
o/$(MODE)/libc/fmt \
|
o/$(MODE)/libc/fmt \
|
||||||
o/$(MODE)/libc/intrin \
|
o/$(MODE)/libc/intrin \
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
#define _ASSERT_H
|
#define _ASSERT_H
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
void __assert_fail(const char *, const char *, int);
|
void __assert_fail(const char *, const char *, int) libcesque;
|
||||||
void unassert(const char *, const char *, int);
|
void unassert(const char *, const char *, int) libcesque;
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#define assert(x) ((void)0)
|
#define assert(x) ((void)0)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
#
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
#
|
#
|
||||||
|
|
|
@ -72,184 +72,184 @@ COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
typedef int sig_atomic_t;
|
typedef int sig_atomic_t;
|
||||||
|
|
||||||
bool32 isatty(int);
|
bool32 isatty(int) libcesque;
|
||||||
char *getcwd(char *, size_t);
|
char *getcwd(char *, size_t) dontthrow;
|
||||||
char *realpath(const char *, char *) __wur;
|
char *realpath(const char *, char *) libcesque __wur;
|
||||||
char *ttyname(int);
|
char *ttyname(int) libcesque;
|
||||||
int access(const char *, int) dontthrow;
|
int access(const char *, int) libcesque;
|
||||||
int chdir(const char *);
|
int chdir(const char *) libcesque;
|
||||||
int chmod(const char *, unsigned);
|
int chmod(const char *, unsigned) libcesque;
|
||||||
int chown(const char *, unsigned, unsigned);
|
int chown(const char *, unsigned, unsigned) libcesque;
|
||||||
int chroot(const char *);
|
int chroot(const char *) libcesque;
|
||||||
int close(int);
|
int close(int) libcesque;
|
||||||
int close_range(unsigned, unsigned, unsigned);
|
int close_range(unsigned, unsigned, unsigned) libcesque;
|
||||||
int closefrom(int);
|
int closefrom(int) libcesque;
|
||||||
int creat(const char *, unsigned);
|
int creat(const char *, unsigned) libcesque;
|
||||||
int dup(int);
|
int dup(int) libcesque;
|
||||||
int dup2(int, int);
|
int dup2(int, int) libcesque;
|
||||||
int dup3(int, int, int);
|
int dup3(int, int, int) libcesque;
|
||||||
int execl(const char *, const char *, ...) nullterminated();
|
int execl(const char *, const char *, ...) nullterminated() libcesque;
|
||||||
int execle(const char *, const char *, ...) nullterminated((1));
|
int execle(const char *, const char *, ...) nullterminated((1)) libcesque;
|
||||||
int execlp(const char *, const char *, ...) nullterminated();
|
int execlp(const char *, const char *, ...) nullterminated() libcesque;
|
||||||
int execv(const char *, char *const[]);
|
int execv(const char *, char *const[]) libcesque;
|
||||||
int execve(const char *, char *const[], char *const[]);
|
int execve(const char *, char *const[], char *const[]) libcesque;
|
||||||
int execvp(const char *, char *const[]);
|
int execvp(const char *, char *const[]) libcesque;
|
||||||
int faccessat(int, const char *, int, int);
|
int faccessat(int, const char *, int, int) libcesque;
|
||||||
int fchdir(int);
|
int fchdir(int) libcesque;
|
||||||
int fchmod(int, unsigned) dontthrow;
|
int fchmod(int, unsigned) libcesque;
|
||||||
int fchmodat(int, const char *, unsigned, int);
|
int fchmodat(int, const char *, unsigned, int) libcesque;
|
||||||
int fchown(int, unsigned, unsigned);
|
int fchown(int, unsigned, unsigned) libcesque;
|
||||||
int fchownat(int, const char *, unsigned, unsigned, int);
|
int fchownat(int, const char *, unsigned, unsigned, int) libcesque;
|
||||||
int fcntl(int, int, ...);
|
int fcntl(int, int, ...) libcesque;
|
||||||
int fdatasync(int);
|
int fdatasync(int) libcesque;
|
||||||
int fexecve(int, char *const[], char *const[]);
|
int fexecve(int, char *const[], char *const[]) libcesque;
|
||||||
int flock(int, int);
|
int flock(int, int) libcesque;
|
||||||
int fork(void);
|
int fork(void) libcesque;
|
||||||
int fsync(int);
|
int fsync(int) libcesque;
|
||||||
int ftruncate(int, int64_t);
|
int ftruncate(int, int64_t) libcesque;
|
||||||
int getdomainname(char *, size_t);
|
int getdomainname(char *, size_t) libcesque;
|
||||||
int getgroups(int, unsigned[]);
|
int getgroups(int, unsigned[]) libcesque;
|
||||||
int gethostname(char *, size_t);
|
int gethostname(char *, size_t) libcesque;
|
||||||
int getloadavg(double *, int);
|
int getloadavg(double *, int) libcesque;
|
||||||
int getpgid(int) libcesque;
|
int getpgid(int) libcesque;
|
||||||
int getpgrp(void) nosideeffect;
|
int getpgrp(void) libcesque nosideeffect;
|
||||||
int getpid(void) nosideeffect libcesque;
|
int getpid(void) libcesque nosideeffect;
|
||||||
int getppid(void);
|
int getppid(void) libcesque;
|
||||||
int getpriority(int, unsigned);
|
int getpriority(int, unsigned) libcesque;
|
||||||
int getsid(int) nosideeffect libcesque;
|
int getsid(int) nosideeffect libcesque;
|
||||||
int ioctl(int, unsigned long, ...);
|
int ioctl(int, unsigned long, ...) libcesque;
|
||||||
int issetugid(void);
|
int issetugid(void) libcesque;
|
||||||
int kill(int, int);
|
int kill(int, int) libcesque;
|
||||||
int killpg(int, int);
|
int killpg(int, int) libcesque;
|
||||||
int lchmod(const char *, unsigned);
|
int lchmod(const char *, unsigned) libcesque;
|
||||||
int lchown(const char *, unsigned, unsigned);
|
int lchown(const char *, unsigned, unsigned) libcesque;
|
||||||
int link(const char *, const char *) dontthrow;
|
int link(const char *, const char *) libcesque;
|
||||||
int linkat(int, const char *, int, const char *, int);
|
int linkat(int, const char *, int, const char *, int) libcesque;
|
||||||
int mincore(void *, size_t, unsigned char *);
|
int mincore(void *, size_t, unsigned char *) libcesque;
|
||||||
int mkdir(const char *, unsigned);
|
int mkdir(const char *, unsigned) libcesque;
|
||||||
int mkdirat(int, const char *, unsigned);
|
int mkdirat(int, const char *, unsigned) libcesque;
|
||||||
int mknod(const char *, unsigned, uint64_t);
|
int mknod(const char *, unsigned, uint64_t) libcesque;
|
||||||
int nice(int);
|
int nice(int) libcesque;
|
||||||
int open(const char *, int, ...);
|
int open(const char *, int, ...) libcesque;
|
||||||
int openat(int, const char *, int, ...);
|
int openat(int, const char *, int, ...) libcesque;
|
||||||
int pause(void);
|
int pause(void) libcesque;
|
||||||
int pipe(int[hasatleast 2]);
|
int pipe(int[hasatleast 2]) libcesque;
|
||||||
int pipe2(int[hasatleast 2], int);
|
int pipe2(int[hasatleast 2], int) libcesque;
|
||||||
int posix_fadvise(int, int64_t, int64_t, int);
|
int posix_fadvise(int, int64_t, int64_t, int) libcesque;
|
||||||
int posix_madvise(void *, uint64_t, int);
|
int posix_madvise(void *, uint64_t, int) libcesque;
|
||||||
int raise(int);
|
int raise(int) libcesque;
|
||||||
int reboot(int);
|
int reboot(int) libcesque;
|
||||||
int remove(const char *);
|
int remove(const char *) libcesque;
|
||||||
int rename(const char *, const char *);
|
int rename(const char *, const char *) libcesque;
|
||||||
int renameat(int, const char *, int, const char *);
|
int renameat(int, const char *, int, const char *) libcesque;
|
||||||
int rmdir(const char *);
|
int rmdir(const char *) libcesque;
|
||||||
int sched_yield(void);
|
int sched_yield(void) libcesque;
|
||||||
int setegid(unsigned);
|
int setegid(unsigned) libcesque;
|
||||||
int seteuid(unsigned);
|
int seteuid(unsigned) libcesque;
|
||||||
int setfsgid(unsigned);
|
int setfsgid(unsigned) libcesque;
|
||||||
int setfsuid(unsigned);
|
int setfsuid(unsigned) libcesque;
|
||||||
int setgid(unsigned);
|
int setgid(unsigned) libcesque;
|
||||||
int setgroups(size_t, const unsigned[]);
|
int setgroups(size_t, const unsigned[]) libcesque;
|
||||||
int setpgid(int, int);
|
int setpgid(int, int) libcesque;
|
||||||
int setpgrp(void);
|
int setpgrp(void) libcesque;
|
||||||
int setpriority(int, unsigned, int);
|
int setpriority(int, unsigned, int) libcesque;
|
||||||
int setregid(unsigned, unsigned);
|
int setregid(unsigned, unsigned) libcesque;
|
||||||
int setreuid(unsigned, unsigned);
|
int setreuid(unsigned, unsigned) libcesque;
|
||||||
int setsid(void);
|
int setsid(void) libcesque;
|
||||||
int setuid(unsigned);
|
int setuid(unsigned) libcesque;
|
||||||
int shm_open(const char *, int, unsigned);
|
int shm_open(const char *, int, unsigned) libcesque;
|
||||||
int shm_unlink(const char *);
|
int shm_unlink(const char *) libcesque;
|
||||||
int sigignore(int);
|
int sigignore(int) libcesque;
|
||||||
int siginterrupt(int, int);
|
int siginterrupt(int, int) libcesque;
|
||||||
int symlink(const char *, const char *);
|
int symlink(const char *, const char *) libcesque;
|
||||||
int symlinkat(const char *, int, const char *);
|
int symlinkat(const char *, int, const char *) libcesque;
|
||||||
int tcgetpgrp(int);
|
int tcgetpgrp(int) libcesque;
|
||||||
int tcsetpgrp(int, int);
|
int tcsetpgrp(int, int) libcesque;
|
||||||
int truncate(const char *, int64_t);
|
int truncate(const char *, int64_t) libcesque;
|
||||||
int ttyname_r(int, char *, size_t);
|
int ttyname_r(int, char *, size_t) libcesque;
|
||||||
int unlink(const char *);
|
int unlink(const char *) libcesque;
|
||||||
int unlinkat(int, const char *, int);
|
int unlinkat(int, const char *, int) libcesque;
|
||||||
int usleep(uint64_t);
|
int usleep(uint64_t) libcesque;
|
||||||
int vfork(void) returnstwice;
|
int vfork(void) libcesque returnstwice;
|
||||||
int wait(int *);
|
int wait(int *) libcesque;
|
||||||
int waitpid(int, int *, int);
|
int waitpid(int, int *, int) libcesque;
|
||||||
int64_t clock(void);
|
int64_t clock(void) libcesque;
|
||||||
int64_t time(int64_t *);
|
int64_t time(int64_t *) libcesque;
|
||||||
ssize_t copy_file_range(int, long *, int, long *, size_t, unsigned);
|
ssize_t copy_file_range(int, long *, int, long *, size_t, unsigned) libcesque;
|
||||||
ssize_t lseek(int, int64_t, int);
|
ssize_t lseek(int, int64_t, int) libcesque;
|
||||||
ssize_t pread(int, void *, size_t, int64_t);
|
ssize_t pread(int, void *, size_t, int64_t) libcesque;
|
||||||
ssize_t pwrite(int, const void *, size_t, int64_t);
|
ssize_t pwrite(int, const void *, size_t, int64_t) libcesque;
|
||||||
ssize_t read(int, void *, size_t);
|
ssize_t read(int, void *, size_t) libcesque;
|
||||||
ssize_t readlink(const char *, char *, size_t);
|
ssize_t readlink(const char *, char *, size_t) libcesque;
|
||||||
ssize_t readlinkat(int, const char *, char *, size_t);
|
ssize_t readlinkat(int, const char *, char *, size_t) libcesque;
|
||||||
ssize_t write(int, const void *, size_t);
|
ssize_t write(int, const void *, size_t) libcesque;
|
||||||
unsigned alarm(unsigned);
|
unsigned alarm(unsigned) libcesque;
|
||||||
unsigned getegid(void) nosideeffect;
|
unsigned getegid(void) libcesque nosideeffect;
|
||||||
unsigned geteuid(void) nosideeffect;
|
unsigned geteuid(void) libcesque nosideeffect;
|
||||||
unsigned getgid(void) nosideeffect;
|
unsigned getgid(void) libcesque nosideeffect;
|
||||||
unsigned getuid(void) libcesque;
|
unsigned getuid(void) libcesque;
|
||||||
unsigned sleep(unsigned);
|
unsigned sleep(unsigned) libcesque;
|
||||||
unsigned ualarm(unsigned, unsigned);
|
unsigned ualarm(unsigned, unsigned) libcesque;
|
||||||
unsigned umask(unsigned);
|
unsigned umask(unsigned) libcesque;
|
||||||
void sync(void);
|
void sync(void) libcesque;
|
||||||
|
|
||||||
#if defined(_COSMO_SOURCE) || defined(_GNU_SOURCE)
|
#if defined(_COSMO_SOURCE) || defined(_GNU_SOURCE)
|
||||||
int syncfs(int);
|
int syncfs(int) libcesque;
|
||||||
int prctl(int, ...);
|
int prctl(int, ...) libcesque;
|
||||||
int gettid(void) libcesque;
|
int gettid(void) libcesque;
|
||||||
int setresgid(unsigned, unsigned, unsigned);
|
int setresgid(unsigned, unsigned, unsigned) libcesque;
|
||||||
int setresuid(unsigned, unsigned, unsigned);
|
int setresuid(unsigned, unsigned, unsigned) libcesque;
|
||||||
int getresgid(unsigned *, unsigned *, unsigned *);
|
int getresgid(unsigned *, unsigned *, unsigned *) libcesque;
|
||||||
int getresuid(unsigned *, unsigned *, unsigned *);
|
int getresuid(unsigned *, unsigned *, unsigned *) libcesque;
|
||||||
char *get_current_dir_name(void) __wur;
|
char *get_current_dir_name(void) libcesque __wur;
|
||||||
ssize_t splice(int, int64_t *, int, int64_t *, size_t, unsigned);
|
ssize_t splice(int, int64_t *, int, int64_t *, size_t, unsigned) libcesque;
|
||||||
int memfd_create(const char *, unsigned int);
|
int memfd_create(const char *, unsigned int) libcesque;
|
||||||
int execvpe(const char *, char *const[], char *const[]);
|
int execvpe(const char *, char *const[], char *const[]) libcesque;
|
||||||
int euidaccess(const char *, int);
|
int euidaccess(const char *, int) libcesque;
|
||||||
int eaccess(const char *, int);
|
int eaccess(const char *, int) libcesque;
|
||||||
int madvise(void *, uint64_t, int);
|
int madvise(void *, uint64_t, int) libcesque;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _COSMO_SOURCE
|
#ifdef _COSMO_SOURCE
|
||||||
bool32 fdexists(int);
|
bool32 fdexists(int) libcesque;
|
||||||
bool32 fileexists(const char *);
|
bool32 fileexists(const char *) libcesque;
|
||||||
bool32 ischardev(int);
|
bool32 ischardev(int) libcesque;
|
||||||
bool32 isdirectory(const char *);
|
bool32 isdirectory(const char *) libcesque;
|
||||||
bool32 isexecutable(const char *);
|
bool32 isexecutable(const char *) libcesque;
|
||||||
bool32 isregularfile(const char *);
|
bool32 isregularfile(const char *) libcesque;
|
||||||
bool32 issymlink(const char *);
|
bool32 issymlink(const char *) libcesque;
|
||||||
char *commandv(const char *, char *, size_t);
|
char *commandv(const char *, char *, size_t) libcesque;
|
||||||
int __getcwd(char *, size_t);
|
int __getcwd(char *, size_t) libcesque;
|
||||||
int clone(void *, void *, size_t, int, void *, void *, void *, void *);
|
int clone(void *, void *, size_t, int, void *, void *, void *, void *);
|
||||||
int fadvise(int, uint64_t, uint64_t, int);
|
int fadvise(int, uint64_t, uint64_t, int) libcesque;
|
||||||
int makedirs(const char *, unsigned);
|
int makedirs(const char *, unsigned) libcesque;
|
||||||
int pivot_root(const char *, const char *);
|
int pivot_root(const char *, const char *) libcesque;
|
||||||
int pledge(const char *, const char *);
|
int pledge(const char *, const char *) libcesque;
|
||||||
int seccomp(unsigned, unsigned, void *);
|
int seccomp(unsigned, unsigned, void *) libcesque;
|
||||||
int sys_iopl(int);
|
int sys_iopl(int) libcesque;
|
||||||
int sys_ioprio_get(int, int);
|
int sys_ioprio_get(int, int) libcesque;
|
||||||
int sys_ioprio_set(int, int, int);
|
int sys_ioprio_set(int, int, int) libcesque;
|
||||||
int sys_mlock(const void *, size_t);
|
int sys_mlock(const void *, size_t) libcesque;
|
||||||
int sys_mlock2(const void *, size_t, int);
|
int sys_mlock2(const void *, size_t, int) libcesque;
|
||||||
int sys_mlockall(int);
|
int sys_mlockall(int) libcesque;
|
||||||
int sys_munlock(const void *, size_t);
|
int sys_munlock(const void *, size_t) libcesque;
|
||||||
int sys_munlockall(void);
|
int sys_munlockall(void) libcesque;
|
||||||
int sys_personality(uint64_t);
|
int sys_personality(uint64_t) libcesque;
|
||||||
int sys_ptrace(int, ...);
|
int sys_ptrace(int, ...) libcesque;
|
||||||
int sys_sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
|
int sys_sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
|
||||||
int tmpfd(void);
|
int tmpfd(void) libcesque;
|
||||||
int touch(const char *, unsigned);
|
int touch(const char *, unsigned) libcesque;
|
||||||
int unveil(const char *, const char *);
|
int unveil(const char *, const char *) libcesque;
|
||||||
long ptrace(int, ...);
|
long ptrace(int, ...) libcesque;
|
||||||
ssize_t copyfd(int, int, size_t);
|
ssize_t copyfd(int, int, size_t) libcesque;
|
||||||
ssize_t readansi(int, char *, size_t);
|
ssize_t readansi(int, char *, size_t) libcesque;
|
||||||
ssize_t tinyprint(int, const char *, ...) nullterminated();
|
ssize_t tinyprint(int, const char *, ...) libcesque nullterminated();
|
||||||
void shm_path_np(const char *, char[hasatleast 78]);
|
void shm_path_np(const char *, char[hasatleast 78]) libcesque;
|
||||||
#endif /* _COSMO_SOURCE */
|
#endif /* _COSMO_SOURCE */
|
||||||
|
|
||||||
int __wifstopped(int) pureconst;
|
int __wifstopped(int) libcesque pureconst;
|
||||||
int __wifcontinued(int) pureconst;
|
int __wifcontinued(int) libcesque pureconst;
|
||||||
int __wifsignaled(int) pureconst;
|
int __wifsignaled(int) libcesque pureconst;
|
||||||
|
|
||||||
#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
|
#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
|
||||||
#define lseek64 lseek
|
#define lseek64 lseek
|
||||||
|
|
|
@ -16,10 +16,12 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/assert.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/state.internal.h"
|
#include "libc/calls/state.internal.h"
|
||||||
#include "libc/calls/struct/fd.internal.h"
|
#include "libc/calls/struct/fd.internal.h"
|
||||||
|
#include "libc/calls/struct/sigset.internal.h"
|
||||||
#include "libc/calls/syscall-nt.internal.h"
|
#include "libc/calls/syscall-nt.internal.h"
|
||||||
#include "libc/calls/syscall-sysv.internal.h"
|
#include "libc/calls/syscall-sysv.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
@ -49,13 +51,8 @@ static int close_impl(int fd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__isfdkind(fd, kFdZip)) {
|
if (__isfdkind(fd, kFdZip)) {
|
||||||
if (!__vforked && _weaken(__zipos_close)) {
|
unassert(_weaken(__zipos_close));
|
||||||
return _weaken(__zipos_close)(fd);
|
return _weaken(__zipos_close)(fd);
|
||||||
}
|
|
||||||
if (!IsWindows() && !IsMetal()) {
|
|
||||||
sys_close(fd);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsWindows() && !IsMetal()) {
|
if (!IsWindows() && !IsMetal()) {
|
||||||
|
@ -95,8 +92,18 @@ static int close_impl(int fd) {
|
||||||
* @vforksafe
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
int close(int fd) {
|
int close(int fd) {
|
||||||
int rc = close_impl(fd);
|
int rc;
|
||||||
if (!__vforked) __releasefd(fd);
|
if (__isfdkind(fd, kFdZip)) { // XXX IsWindows()?
|
||||||
|
BLOCK_SIGNALS;
|
||||||
|
__fds_lock();
|
||||||
|
rc = close_impl(fd);
|
||||||
|
if (!__vforked) __releasefd(fd);
|
||||||
|
__fds_unlock();
|
||||||
|
ALLOW_SIGNALS;
|
||||||
|
} else {
|
||||||
|
rc = close_impl(fd);
|
||||||
|
if (!__vforked) __releasefd(fd);
|
||||||
|
}
|
||||||
STRACE("close(%d) → %d% m", fd, rc);
|
STRACE("close(%d) → %d% m", fd, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,4 +66,4 @@ int fadvise(int fd, uint64_t offset, uint64_t len, int advice) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
__strong_reference(fadvise, fadvise64);
|
__weak_reference(fadvise, fadvise64);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Musl Libc │
|
│ Musl Libc │
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
#include "libc/elf/def.h"
|
#include "libc/elf/def.h"
|
||||||
#include "libc/elf/tinyelf.internal.h"
|
#include "libc/elf/tinyelf.internal.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/serialize.h"
|
|
||||||
#include "libc/intrin/directmap.internal.h"
|
#include "libc/intrin/directmap.internal.h"
|
||||||
#include "libc/nt/memory.h"
|
#include "libc/nt/memory.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
#include "libc/serialize.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/map.h"
|
#include "libc/sysv/consts/map.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
|
@ -80,8 +80,9 @@ static bool IsMyDebugBinary(const char *path) {
|
||||||
// contains the same number of bytes of code as our .com executable
|
// contains the same number of bytes of code as our .com executable
|
||||||
// which is currently running in memory.
|
// which is currently running in memory.
|
||||||
if ((size = lseek(fd, 0, SEEK_END)) != -1 &&
|
if ((size = lseek(fd, 0, SEEK_END)) != -1 &&
|
||||||
(dm = sys_mmap(0, size, PROT_READ, MAP_SHARED, fd, 0)).addr !=
|
(dm = sys_mmap((void *)0x12345000000, size, PROT_READ, MAP_SHARED, fd,
|
||||||
MAP_FAILED) {
|
0))
|
||||||
|
.addr != MAP_FAILED) {
|
||||||
if (READ32LE((char *)dm.addr) == READ32LE("\177ELF") &&
|
if (READ32LE((char *)dm.addr) == READ32LE("\177ELF") &&
|
||||||
((Elf64_Ehdr *)dm.addr)->e_machine == GetElfMachine() &&
|
((Elf64_Ehdr *)dm.addr)->e_machine == GetElfMachine() &&
|
||||||
GetElfSymbolValue(dm.addr, "_etext", &value)) {
|
GetElfSymbolValue(dm.addr, "_etext", &value)) {
|
||||||
|
|
|
@ -60,4 +60,4 @@ int fstat(int fd, struct stat *st) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
__strong_reference(fstat, fstat64);
|
__weak_reference(fstat, fstat64);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue