mirror of
https://github.com/jart/cosmopolitan.git
synced 2026-11-08 08:08:04 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af2ef0d223 |
No files matched your search
@@ -60,8 +60,8 @@
|
||||
# build/config.mk
|
||||
|
||||
SHELL = build/bootstrap/cocmd.com
|
||||
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win10
|
||||
MAKEFLAGS += --no-builtin-rules
|
||||
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 win10 xnu
|
||||
MAKEFLAGS += -j --no-builtin-rules
|
||||
|
||||
.SUFFIXES:
|
||||
.DELETE_ON_ERROR:
|
||||
@@ -92,7 +92,6 @@ o/$(MODE): \
|
||||
.UNVEIL = \
|
||||
libc/integral \
|
||||
libc/disclaimer.inc \
|
||||
rwc:/dev/shm \
|
||||
rx:build/bootstrap \
|
||||
rx:o/third_party/gcc \
|
||||
/proc/stat \
|
||||
@@ -128,7 +127,6 @@ include ape/ape.mk # │
|
||||
include libc/fmt/fmt.mk # │
|
||||
include libc/vga/vga.mk #─┘
|
||||
include libc/calls/calls.mk #─┐
|
||||
include third_party/getopt/getopt.mk # │
|
||||
include libc/runtime/runtime.mk # ├──SYSTEMS RUNTIME
|
||||
include libc/crt/crt.mk # │ You can issue system calls
|
||||
include third_party/nsync/nsync.mk # │
|
||||
@@ -152,6 +150,7 @@ include dsp/mpeg/mpeg.mk # │
|
||||
include dsp/dsp.mk # │
|
||||
include third_party/zlib/gz/gz.mk # │
|
||||
include third_party/musl/musl.mk # │
|
||||
include third_party/getopt/getopt.mk # │
|
||||
include libc/libc.mk #─┘
|
||||
include libc/sock/sock.mk #─┐
|
||||
include dsp/tty/tty.mk # ├──ONLINE RUNTIME
|
||||
@@ -172,12 +171,9 @@ include third_party/maxmind/maxmind.mk
|
||||
include net/finger/finger.mk
|
||||
include third_party/double-conversion/test/test.mk
|
||||
include third_party/lua/lua.mk
|
||||
include third_party/tr/tr.mk
|
||||
include third_party/sed/sed.mk
|
||||
include third_party/awk/awk.mk
|
||||
include third_party/hiredis/hiredis.mk
|
||||
include third_party/make/make.mk
|
||||
include third_party/ctags/ctags.mk
|
||||
include third_party/finger/finger.mk
|
||||
include third_party/argon2/argon2.mk
|
||||
include third_party/smallz4/smallz4.mk
|
||||
@@ -194,7 +190,6 @@ include third_party/python/python.mk
|
||||
include tool/build/emucrt/emucrt.mk
|
||||
include tool/build/emubin/emubin.mk
|
||||
include tool/build/build.mk
|
||||
include tool/curl/curl.mk
|
||||
include examples/examples.mk
|
||||
include examples/pyapp/pyapp.mk
|
||||
include examples/pylife/pylife.mk
|
||||
@@ -281,14 +276,14 @@ o/$(MODE)/hdrs-old.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS
|
||||
$(file >$@) $(foreach x,$(HDRS) $(INCS),$(file >>$@,$(x)))
|
||||
|
||||
TAGS: private .UNSANDBOXED = 1
|
||||
TAGS: o/$(MODE)/srcs-old.txt $(SRCS) o/$(MODE)/third_party/ctags/ctags.com
|
||||
TAGS: o/$(MODE)/srcs-old.txt $(SRCS)
|
||||
@$(RM) $@
|
||||
@o/$(MODE)/third_party/ctags/ctags.com $(TAGSFLAGS) -L $< -o $@
|
||||
@$(TAGS) $(TAGSFLAGS) -L $< -o $@
|
||||
|
||||
HTAGS: private .UNSANDBOXED = 1
|
||||
HTAGS: o/$(MODE)/hdrs-old.txt $(HDRS) o/$(MODE)/third_party/ctags/ctags.com
|
||||
HTAGS: o/$(MODE)/hdrs-old.txt $(HDRS)
|
||||
@$(RM) $@
|
||||
@build/htags o/$(MODE)/third_party/ctags/ctags.com -L $< -o $@
|
||||
@build/htags -L $< -o $@
|
||||
|
||||
loc: private .UNSANDBOXED = 1
|
||||
loc: o/$(MODE)/tool/build/summy.com
|
||||
@@ -374,9 +369,11 @@ COSMOPOLITAN_HEADERS = \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_ZLIB \
|
||||
THIRD_PARTY_ZLIB_GZ \
|
||||
THIRD_PARTY_REGEX
|
||||
|
||||
o/$(MODE)/cosmopolitan.a: \
|
||||
o/$(MODE)/cosmopolitan.a: \
|
||||
$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_A_OBJS))
|
||||
|
||||
o/cosmopolitan.h: \
|
||||
@@ -439,9 +436,9 @@ $(SRCS):
|
||||
$(HDRS):
|
||||
$(INCS):
|
||||
.DEFAULT:
|
||||
@$(ECHO)
|
||||
@$(ECHO) NOTE: deleting o/$(MODE)/depend because of an unspecified prerequisite: $@
|
||||
@$(ECHO)
|
||||
@$(ECHO) >&2
|
||||
@$(ECHO) NOTE: deleting o/$(MODE)/depend because of an unspecified prerequisite: $@ >&2
|
||||
@$(ECHO) >&2
|
||||
$(RM) o/$(MODE)/depend
|
||||
|
||||
-include o/$(MODE)/depend
|
||||
@@ -23,8 +23,8 @@ If you're doing your development work on Linux or BSD then you need just
|
||||
five files to get started. Here's what you do on Linux:
|
||||
|
||||
```sh
|
||||
wget https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-2.2.zip
|
||||
unzip cosmopolitan-amalgamation-2.2.zip
|
||||
wget https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-2.1.1.zip
|
||||
unzip cosmopolitan-amalgamation-2.1.1.zip
|
||||
printf 'main() { printf("hello world\\n"); }\n' >hello.c
|
||||
gcc -g -Os -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \
|
||||
-fno-omit-frame-pointer -pg -mnop-mcount -mno-tls-direct-seg-refs -gdwarf-4 \
|
||||
@@ -57,13 +57,9 @@ sudo sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/status'
|
||||
|
||||
Since we used the `ape-no-modify-self.o` bootloader (rather than
|
||||
`ape.o`) your executable will not modify itself when it's run. What
|
||||
it'll instead do, is extract a 4kb program (the [APE loader](https://justine.lol/apeloader/))
|
||||
to `${TMPDIR:-${HOME:-.}}` that maps your program into memory without
|
||||
needing to copy it. The APE loader must be in an executable location
|
||||
(e.g. not stored on a `noexec` mount) for it to run. See below for
|
||||
alternatives:
|
||||
|
||||
It's possible to install the APE loader systemwide as follows.
|
||||
it'll instead do, is extract a 4kb program to `${TMPDIR:-${HOME:-.}}`
|
||||
that maps your program into memory without needing to copy it. It's
|
||||
possible to install the APE loader systemwide as follows.
|
||||
|
||||
```sh
|
||||
# System-Wide APE Install
|
||||
@@ -250,16 +246,12 @@ gdb foo.com -ex 'add-symbol-file foo.com.dbg 0x401000'
|
||||
| AMD | K8 Venus | 2005 |
|
||||
| Intel | Core | 2006 |
|
||||
| Linux | 2.6.18 | 2007 |
|
||||
| Windows | 8 [1] | 2012 |
|
||||
| Windows | 8 | 2012 |
|
||||
| Mac OS X | 15.6 | 2018 |
|
||||
| OpenBSD | 6.4 | 2018 |
|
||||
| FreeBSD | 13 | 2020 |
|
||||
| NetBSD | 9.2 | 2021 |
|
||||
|
||||
[1] See our [vista branch](https://github.com/jart/cosmopolitan/tree/vista)
|
||||
for a community supported version of Cosmopolitan that works on Windows
|
||||
Vista and Windows 7.
|
||||
|
||||
## Special Thanks
|
||||
|
||||
Funding for this project is crowdsourced using
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "ape/macros.internal.h"
|
||||
#include "ape/notice.inc"
|
||||
#include "ape/relocations.h"
|
||||
#include "libc/calls/metalfile.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/elf/def.h"
|
||||
#include "libc/macho.internal.h"
|
||||
@@ -113,33 +112,7 @@ cstr: .endobj cstr,globl,hidden # ←for gdb readability
|
||||
//
|
||||
// @param dl is drive number
|
||||
// @noreturn
|
||||
ape_mz:
|
||||
#if SupportsWindows() || SupportsMetal()
|
||||
.asciz "MZqFpD='\n" # Mark 'Zibo' Joseph Zbikowski
|
||||
// # in real mode
|
||||
// dec %bp
|
||||
// pop %dx
|
||||
// jno 0x4a
|
||||
// jo 0x4a
|
||||
//
|
||||
// # in legacy mode
|
||||
// push %ebp
|
||||
// pop %edx
|
||||
// jno 0x4a
|
||||
// jo 0x4a
|
||||
//
|
||||
// # 64-bit mode
|
||||
// rex.WRB
|
||||
// pop %r10
|
||||
// jno 0x4a
|
||||
// jo 0x4a
|
||||
#else
|
||||
// Avoid virus scanner reputation damage when targeting System Five.
|
||||
.asciz "jartsr='\n" # Justine Alexandra Roberts Tunney
|
||||
// push $0x61
|
||||
// jb 0x78
|
||||
// jae 0x78
|
||||
#endif
|
||||
ape_mz: .asciz "MZqFpD='\n" # Mark 'Zibo' Joseph Zbikowski
|
||||
.short 0x1000 # MZ: lowers upper bound load / 16
|
||||
.short 0xf800 # MZ: roll greed on bss
|
||||
.short 0 # MZ: lower bound on stack segment
|
||||
@@ -158,9 +131,6 @@ ape_mz:
|
||||
.long RVA(ape_pe) # PE: the new technology
|
||||
#else
|
||||
.long 0
|
||||
.org 0x78
|
||||
pop %rax
|
||||
jmp _start
|
||||
#endif
|
||||
.endfn ape_mz,globl,hidden
|
||||
|
||||
@@ -282,9 +252,6 @@ pc: cld
|
||||
xor %dh,%dh # current head
|
||||
mov $v_ape_realsectors,%di # total sectors
|
||||
3: call pcread
|
||||
mov %es,%si # addr += 512
|
||||
add $512>>4,%si
|
||||
mov %si,%es
|
||||
dec %di
|
||||
jnz 3b
|
||||
6: ljmp $0,$REAL(realmodeloader)
|
||||
@@ -373,7 +340,6 @@ dsknfo: push %bx
|
||||
pop %ds
|
||||
xchg %bx,%ax
|
||||
stosw #→ pc_drive_type, pc_drive_last_sector
|
||||
scasb
|
||||
xchg %cx,%ax
|
||||
stosw #→ pc_drive_last_cylinder
|
||||
xchg %dx,%ax
|
||||
@@ -412,6 +378,9 @@ pcread: push %ax
|
||||
pop %cx
|
||||
pop %ax
|
||||
jc 9f
|
||||
mov %es,%si # addr += 512
|
||||
add $512>>4,%si
|
||||
mov %si,%es
|
||||
inc %al # ++sector
|
||||
cmp mm+"struct mman::pc_drive_last_sector",%al
|
||||
jbe 2f
|
||||
@@ -581,9 +550,6 @@ ape_disk:
|
||||
|
||||
#if SupportsWindows() || SupportsMetal() || SupportsXnu()
|
||||
apesh: .ascii "\n@\n#'\"\n" # sixth edition shebang
|
||||
.ascii "m=\"$(uname -m)\"\n"
|
||||
|
||||
.ascii "if [ \"$m\" = x86_64 ] || [ \"$m\" = amd64 ]; then\n"
|
||||
// Until all operating systems can be updated to support APE,
|
||||
// we have a beautiful, yet imperfect workaround, which is to
|
||||
// modify the binary to follow the local system's convention.
|
||||
@@ -685,332 +651,17 @@ apesh: .ascii "\n@\n#'\"\n" # sixth edition shebang
|
||||
.ascii "o=\"$t\"\n"
|
||||
.ascii "exec \"$o\" \"$@\"\n"
|
||||
#endif /* APE_NO_MODIFY_SELF */
|
||||
.ascii "exit $?\n"
|
||||
.ascii "R=$?\n"
|
||||
.ascii "if [ \"$(uname -m)\" != x86_64 ]; then\n"
|
||||
.ascii "Q=\"$(command -v qemu-x86_64)\" &&\n"
|
||||
.ascii "exec \"$Q\" \"$o\" \"$@\"\n"
|
||||
#ifndef APE_NO_MODIFY_SELF
|
||||
.ascii "else\n" # means argv[0] was wrong
|
||||
.ascii " exec \"$o\" \"$@\"\n" # so do a path resolution
|
||||
#endif /* APE_NO_MODIFY_SELF */
|
||||
.ascii "fi\n"
|
||||
|
||||
.ascii "PHDRS='' <<'@'\n"
|
||||
.ascii "exit $R\n"
|
||||
.endobj apesh
|
||||
// elf program headers get inserted here
|
||||
// because they need to be in the first 4096 bytes
|
||||
.section .emush,"a",@progbits
|
||||
emush: .ascii "\n@\n#'\"\n"
|
||||
.ascii "s=\"$(uname -s)\"\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.1\"\n"
|
||||
|
||||
// Blink for Apple Silicon, e.g. M1 Macbook
|
||||
.ascii "if [ \"$s\" = Darwin ] && [ \"$m\" = arm64 ]; then\n"
|
||||
.ascii "if ! [ -x \"$e\" ]; then\n"
|
||||
.ascii "echo \"extracting blink-darwin-arm64 to ${e}\" >&2\n"
|
||||
.ascii "dd if=\"$o\" bs=1 skip=$(("
|
||||
.byte blink_darwin_arm64_b9
|
||||
.byte blink_darwin_arm64_b8
|
||||
.byte blink_darwin_arm64_b7
|
||||
.byte blink_darwin_arm64_b6
|
||||
.byte blink_darwin_arm64_b5
|
||||
.byte blink_darwin_arm64_b4
|
||||
.byte blink_darwin_arm64_b3
|
||||
.byte blink_darwin_arm64_b2
|
||||
.byte blink_darwin_arm64_b1
|
||||
.byte blink_darwin_arm64_b0
|
||||
.ascii ")) count=$(("
|
||||
.byte blink_darwin_arm64_size_b9
|
||||
.byte blink_darwin_arm64_size_b8
|
||||
.byte blink_darwin_arm64_size_b7
|
||||
.byte blink_darwin_arm64_size_b6
|
||||
.byte blink_darwin_arm64_size_b5
|
||||
.byte blink_darwin_arm64_size_b4
|
||||
.byte blink_darwin_arm64_size_b3
|
||||
.byte blink_darwin_arm64_size_b2
|
||||
.byte blink_darwin_arm64_size_b1
|
||||
.byte blink_darwin_arm64_size_b0
|
||||
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
|
||||
.ascii "mv -f \"$e.$$\" \"$e\"\n"
|
||||
.ascii "chmod +x \"$e\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
|
||||
// Blink for Aarch64 Linux, e.g. Raspberry Pi
|
||||
.ascii "if [ \"$s\" = Linux ]; then\n"
|
||||
.ascii "if [ \"$m\" = aarch64 ] || [ \"$m\" = arm64 ]; then\n"
|
||||
.ascii "if ! [ -x \"$e\" ]; then\n"
|
||||
.ascii "echo \"extracting blink-aarch64 to ${e}\" >&2\n"
|
||||
.ascii "dd if=\"$o\" bs=1 skip=$(("
|
||||
.byte blink_aarch64_b9
|
||||
.byte blink_aarch64_b8
|
||||
.byte blink_aarch64_b7
|
||||
.byte blink_aarch64_b6
|
||||
.byte blink_aarch64_b5
|
||||
.byte blink_aarch64_b4
|
||||
.byte blink_aarch64_b3
|
||||
.byte blink_aarch64_b2
|
||||
.byte blink_aarch64_b1
|
||||
.byte blink_aarch64_b0
|
||||
.ascii ")) count=$(("
|
||||
.byte blink_aarch64_size_b9
|
||||
.byte blink_aarch64_size_b8
|
||||
.byte blink_aarch64_size_b7
|
||||
.byte blink_aarch64_size_b6
|
||||
.byte blink_aarch64_size_b5
|
||||
.byte blink_aarch64_size_b4
|
||||
.byte blink_aarch64_size_b3
|
||||
.byte blink_aarch64_size_b2
|
||||
.byte blink_aarch64_size_b1
|
||||
.byte blink_aarch64_size_b0
|
||||
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
|
||||
.ascii "mv -f \"$e.$$\" \"$e\"\n"
|
||||
.ascii "chmod +x \"$e\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "fi\n"
|
||||
|
||||
// Blink for Linux Generic ARM
|
||||
.ascii "if [ \"$s\" = Linux ] && [ \"${m#arm}\" != \"$m\" ]; then\n"
|
||||
.ascii "if ! [ -x \"$e\" ]; then\n"
|
||||
.ascii "echo \"extracting blink-arm to ${e}\" >&2\n"
|
||||
.ascii "dd if=\"$o\" bs=1 skip=$(("
|
||||
.byte blink_arm_b9
|
||||
.byte blink_arm_b8
|
||||
.byte blink_arm_b7
|
||||
.byte blink_arm_b6
|
||||
.byte blink_arm_b5
|
||||
.byte blink_arm_b4
|
||||
.byte blink_arm_b3
|
||||
.byte blink_arm_b2
|
||||
.byte blink_arm_b1
|
||||
.byte blink_arm_b0
|
||||
.ascii ")) count=$(("
|
||||
.byte blink_arm_size_b9
|
||||
.byte blink_arm_size_b8
|
||||
.byte blink_arm_size_b7
|
||||
.byte blink_arm_size_b6
|
||||
.byte blink_arm_size_b5
|
||||
.byte blink_arm_size_b4
|
||||
.byte blink_arm_size_b3
|
||||
.byte blink_arm_size_b2
|
||||
.byte blink_arm_size_b1
|
||||
.byte blink_arm_size_b0
|
||||
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
|
||||
.ascii "mv -f \"$e.$$\" \"$e\"\n"
|
||||
.ascii "chmod +x \"$e\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
|
||||
// Blink for Linux on Legacy x86
|
||||
.ascii "if [ \"$s\" = Linux ]; then\n"
|
||||
.ascii "if [ \"$m\" = i686 ] || [ \"$m\" = i386 ]; then\n"
|
||||
.ascii "if ! [ -x \"$e\" ]; then\n"
|
||||
.ascii "echo \"extracting blink-i486 to ${e}\" >&2\n"
|
||||
.ascii "dd if=\"$o\" bs=1 skip=$(("
|
||||
.byte blink_i486_b9
|
||||
.byte blink_i486_b8
|
||||
.byte blink_i486_b7
|
||||
.byte blink_i486_b6
|
||||
.byte blink_i486_b5
|
||||
.byte blink_i486_b4
|
||||
.byte blink_i486_b3
|
||||
.byte blink_i486_b2
|
||||
.byte blink_i486_b1
|
||||
.byte blink_i486_b0
|
||||
.ascii ")) count=$(("
|
||||
.byte blink_i486_size_b9
|
||||
.byte blink_i486_size_b8
|
||||
.byte blink_i486_size_b7
|
||||
.byte blink_i486_size_b6
|
||||
.byte blink_i486_size_b5
|
||||
.byte blink_i486_size_b4
|
||||
.byte blink_i486_size_b3
|
||||
.byte blink_i486_size_b2
|
||||
.byte blink_i486_size_b1
|
||||
.byte blink_i486_size_b0
|
||||
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
|
||||
.ascii "mv -f \"$e.$$\" \"$e\"\n"
|
||||
.ascii "chmod +x \"$e\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "fi\n"
|
||||
|
||||
// Blink for Linux on RISC-V
|
||||
.ascii "if [ \"$s\" = Linux ] && [ \"$m\" = riscv64 ]; then\n"
|
||||
.ascii "if ! [ -x \"$e\" ]; then\n"
|
||||
.ascii "echo \"extracting blink-riscv64 to ${e}\" >&2\n"
|
||||
.ascii "dd if=\"$o\" bs=1 skip=$(("
|
||||
.byte blink_riscv64_b9
|
||||
.byte blink_riscv64_b8
|
||||
.byte blink_riscv64_b7
|
||||
.byte blink_riscv64_b6
|
||||
.byte blink_riscv64_b5
|
||||
.byte blink_riscv64_b4
|
||||
.byte blink_riscv64_b3
|
||||
.byte blink_riscv64_b2
|
||||
.byte blink_riscv64_b1
|
||||
.byte blink_riscv64_b0
|
||||
.ascii ")) count=$(("
|
||||
.byte blink_riscv64_size_b9
|
||||
.byte blink_riscv64_size_b8
|
||||
.byte blink_riscv64_size_b7
|
||||
.byte blink_riscv64_size_b6
|
||||
.byte blink_riscv64_size_b5
|
||||
.byte blink_riscv64_size_b4
|
||||
.byte blink_riscv64_size_b3
|
||||
.byte blink_riscv64_size_b2
|
||||
.byte blink_riscv64_size_b1
|
||||
.byte blink_riscv64_size_b0
|
||||
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
|
||||
.ascii "mv -f \"$e.$$\" \"$e\"\n"
|
||||
.ascii "chmod +x \"$e\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
|
||||
// Blink for Linux on MIPS Little Endian, e.g. Ubiquiti EdgerouterX
|
||||
.ascii "if [ \"$s\" = Linux ] && [ \"$m\" = mips ]; then\n"
|
||||
.ascii "if ! [ -x \"$e\" ]; then\n"
|
||||
.ascii "echo \"extracting blink-mipsel to ${e}\" >&2\n"
|
||||
.ascii "dd if=\"$o\" bs=1 skip=$(("
|
||||
.byte blink_mipsel_b9
|
||||
.byte blink_mipsel_b8
|
||||
.byte blink_mipsel_b7
|
||||
.byte blink_mipsel_b6
|
||||
.byte blink_mipsel_b5
|
||||
.byte blink_mipsel_b4
|
||||
.byte blink_mipsel_b3
|
||||
.byte blink_mipsel_b2
|
||||
.byte blink_mipsel_b1
|
||||
.byte blink_mipsel_b0
|
||||
.ascii ")) count=$(("
|
||||
.byte blink_mipsel_size_b9
|
||||
.byte blink_mipsel_size_b8
|
||||
.byte blink_mipsel_size_b7
|
||||
.byte blink_mipsel_size_b6
|
||||
.byte blink_mipsel_size_b5
|
||||
.byte blink_mipsel_size_b4
|
||||
.byte blink_mipsel_size_b3
|
||||
.byte blink_mipsel_size_b2
|
||||
.byte blink_mipsel_size_b1
|
||||
.byte blink_mipsel_size_b0
|
||||
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
|
||||
.ascii "mv -f \"$e.$$\" \"$e\"\n"
|
||||
.ascii "chmod +x \"$e\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
|
||||
// Blink for Linux on PowerPC 64 Little Endian, e.g. Raptor
|
||||
.ascii "if [ \"$s\" = Linux ] && [ \"$m\" = ppc64le ]; then\n"
|
||||
.ascii "if ! [ -x \"$e\" ]; then\n"
|
||||
.ascii "echo \"extracting blink-powerpc64le to ${e}\" >&2\n"
|
||||
.ascii "dd if=\"$o\" bs=1 skip=$(("
|
||||
.byte blink_powerpc64le_b9
|
||||
.byte blink_powerpc64le_b8
|
||||
.byte blink_powerpc64le_b7
|
||||
.byte blink_powerpc64le_b6
|
||||
.byte blink_powerpc64le_b5
|
||||
.byte blink_powerpc64le_b4
|
||||
.byte blink_powerpc64le_b3
|
||||
.byte blink_powerpc64le_b2
|
||||
.byte blink_powerpc64le_b1
|
||||
.byte blink_powerpc64le_b0
|
||||
.ascii ")) count=$(("
|
||||
.byte blink_powerpc64le_size_b9
|
||||
.byte blink_powerpc64le_size_b8
|
||||
.byte blink_powerpc64le_size_b7
|
||||
.byte blink_powerpc64le_size_b6
|
||||
.byte blink_powerpc64le_size_b5
|
||||
.byte blink_powerpc64le_size_b4
|
||||
.byte blink_powerpc64le_size_b3
|
||||
.byte blink_powerpc64le_size_b2
|
||||
.byte blink_powerpc64le_size_b1
|
||||
.byte blink_powerpc64le_size_b0
|
||||
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
|
||||
.ascii "mv -f \"$e.$$\" \"$e\"\n"
|
||||
.ascii "chmod +x \"$e\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
|
||||
// Blink for Linux on PowerPC, e.g. Old Macintosh
|
||||
.ascii "if [ \"$s\" = Linux ] && [ \"$m\" = ppc ]; then\n"
|
||||
.ascii "if ! [ -x \"$e\" ]; then\n"
|
||||
.ascii "echo \"extracting blink-powerpc to ${e}\" >&2\n"
|
||||
.ascii "dd if=\"$o\" bs=1 skip=$(("
|
||||
.byte blink_powerpc_b9
|
||||
.byte blink_powerpc_b8
|
||||
.byte blink_powerpc_b7
|
||||
.byte blink_powerpc_b6
|
||||
.byte blink_powerpc_b5
|
||||
.byte blink_powerpc_b4
|
||||
.byte blink_powerpc_b3
|
||||
.byte blink_powerpc_b2
|
||||
.byte blink_powerpc_b1
|
||||
.byte blink_powerpc_b0
|
||||
.ascii ")) count=$(("
|
||||
.byte blink_powerpc_size_b9
|
||||
.byte blink_powerpc_size_b8
|
||||
.byte blink_powerpc_size_b7
|
||||
.byte blink_powerpc_size_b6
|
||||
.byte blink_powerpc_size_b5
|
||||
.byte blink_powerpc_size_b4
|
||||
.byte blink_powerpc_size_b3
|
||||
.byte blink_powerpc_size_b2
|
||||
.byte blink_powerpc_size_b1
|
||||
.byte blink_powerpc_size_b0
|
||||
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
|
||||
.ascii "mv -f \"$e.$$\" \"$e\"\n"
|
||||
.ascii "chmod +x \"$e\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
|
||||
// Blink for Linux on IBM Mainframes
|
||||
.ascii "if [ \"$s\" = Linux ] && [ \"$m\" = s390x ]; then\n"
|
||||
.ascii "if ! [ -x \"$e\" ]; then\n"
|
||||
.ascii "echo \"extracting blink-s390x to ${e}\" >&2\n"
|
||||
.ascii "dd if=\"$o\" bs=1 skip=$(("
|
||||
.byte blink_s390x_b9
|
||||
.byte blink_s390x_b8
|
||||
.byte blink_s390x_b7
|
||||
.byte blink_s390x_b6
|
||||
.byte blink_s390x_b5
|
||||
.byte blink_s390x_b4
|
||||
.byte blink_s390x_b3
|
||||
.byte blink_s390x_b2
|
||||
.byte blink_s390x_b1
|
||||
.byte blink_s390x_b0
|
||||
.ascii ")) count=$(("
|
||||
.byte blink_s390x_size_b9
|
||||
.byte blink_s390x_size_b8
|
||||
.byte blink_s390x_size_b7
|
||||
.byte blink_s390x_size_b6
|
||||
.byte blink_s390x_size_b5
|
||||
.byte blink_s390x_size_b4
|
||||
.byte blink_s390x_size_b3
|
||||
.byte blink_s390x_size_b2
|
||||
.byte blink_s390x_size_b1
|
||||
.byte blink_s390x_size_b0
|
||||
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
|
||||
.ascii "mv -f \"$e.$$\" \"$e\"\n"
|
||||
.ascii "chmod +x \"$e\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
|
||||
.ascii "echo unsupported architecture >&2\n"
|
||||
.rept 16
|
||||
.ascii "exit 127\n"
|
||||
.endr
|
||||
|
||||
.ascii "exit 1\n"
|
||||
.endobj emush
|
||||
#ifdef APE_LOADER
|
||||
.section .ape.loader,"a",@progbits
|
||||
.align 64
|
||||
@@ -1430,42 +1081,6 @@ ape_idata_idt:
|
||||
ape_idata_idtend:
|
||||
.previous
|
||||
|
||||
.section .piro.data.sort.metal_gdt,"aw",@progbits
|
||||
.align 8
|
||||
_gdt:
|
||||
// ┌G:granularity (1 → limit *= 0x1000)
|
||||
// │┌D/B:default operation size (0 = 16|64bit, 1 = 32-bit)
|
||||
// ││┌L:long mode
|
||||
// │││┌AVL:this bit is thine (1<<52)
|
||||
// ││││ ┌P:present
|
||||
// ││││ │┌DPL:privilege
|
||||
// ││││ ││ ┌─────────data/code(1)
|
||||
// ││││ ││ │┌────data(0)──────code(1)
|
||||
// ││││ ││ ││┌───conforming───expand-down
|
||||
// ││││ ││ │││┌──writeable────readable
|
||||
// ││││ ││ ││││┌─accessed─────accessed
|
||||
// ││││ ││ │││││
|
||||
// ││││ ┌──││─│││││───────────────────────────────┐
|
||||
// ┌───││││─│──││─│││││───────────┐ │
|
||||
// ┌───┴──┐││││┌┴─┐│├┐│││││┌──────────┴───────────┐┌──────┴───────┐
|
||||
// │ ││││││ ││││││││││ base address││ segment limit│
|
||||
// │ ││││││ ││││││││││ 32 bits││ 20 bits│
|
||||
// │ ││││││ ││││││││││ ││ │
|
||||
// 6666555555555544444444443333333333222222222211111111110000000000
|
||||
// 3210987654321098765432109876543210987654321098765432109876543210
|
||||
// │ ││││││ ││││││││││ ││ │
|
||||
.quad 0b0000000000000000000000000000000000000000000000000000000000000000 # 0
|
||||
.quad 0b0000000000001111100110100000000000000000000000001111111111111111 # 8
|
||||
.quad 0b0000000000001111100100100000000000000000000000001111111111111111 #16
|
||||
.quad 0b0000000011001111100110100000000000000000000000001111111111111111 #24
|
||||
.quad 0b0000000011001111100100100000000000000000000000001111111111111111 #32
|
||||
.quad 0b0000000010101111100110110000000000000000000000001111111111111111 #40
|
||||
.quad 0b0000000010101111100100110000000000000000000000001111111111111111 #48
|
||||
.tssdescstub _tss #56,64
|
||||
_gdt_end:
|
||||
.endobj _gdt,global,hidden
|
||||
.previous
|
||||
|
||||
.section .piro.data.sort.iat.1,"aw",@progbits
|
||||
.type ape_idata_iatend,@object
|
||||
.type ape_idata_iat,@object
|
||||
@@ -1523,21 +1138,48 @@ sconf: .short 1843200/*hz*/ / 16/*wut*/ / 9600/*baud*/
|
||||
|
||||
// Global Descriptor Table
|
||||
.align 8
|
||||
_gdtrlo:
|
||||
.short 2f-_gdtlo-1 # table byte length
|
||||
.long REAL(_gdtlo) # table address (base memory space)
|
||||
.endobj _gdtrlo,global,hidden
|
||||
_gdtrphy:
|
||||
.short 2f-1f-1 # table byte length
|
||||
.long REAL(1f) # table address (physical space)
|
||||
.endobj _gdtrphy,global,hidden
|
||||
_gdtr:
|
||||
.short _gdt_end-_gdt-1 # table byte length
|
||||
.quad _gdt # table address (final virtual space)
|
||||
.short 2f-1f-1 # table byte length
|
||||
.quad 1f # table address (final virtual space)
|
||||
.endobj _gdtr,global,hidden
|
||||
.align 8
|
||||
// Partial GDT with descriptors for switching to unreal mode or long mode.
|
||||
_gdtlo = .-GDT_LEGACY_DATA
|
||||
_gdt:
|
||||
1:
|
||||
// ┌G:granularity (1 → limit *= 0x1000)
|
||||
// │┌D/B:default operation size (0 = 16|64bit, 1 = 32-bit)
|
||||
// ││┌L:long mode
|
||||
// │││┌AVL:this bit is thine (1<<52)
|
||||
// ││││ ┌P:present
|
||||
// ││││ │┌DPL:privilege
|
||||
// ││││ ││ ┌─────────data/code(1)
|
||||
// ││││ ││ │┌────data(0)──────code(1)
|
||||
// ││││ ││ ││┌───conforming───expand-down
|
||||
// ││││ ││ │││┌──writeable────readable
|
||||
// ││││ ││ ││││┌─accessed─────accessed
|
||||
// ││││ ││ │││││
|
||||
// ││││ ┌──││─│││││───────────────────────────────┐
|
||||
// ┌───││││─│──││─│││││───────────┐ │
|
||||
// ┌───┴──┐││││┌┴─┐│├┐│││││┌──────────┴───────────┐┌──────┴───────┐
|
||||
// │ ││││││ ││││││││││ base address││ segment limit│
|
||||
// │ ││││││ ││││││││││ 32 bits││ 20 bits│
|
||||
// │ ││││││ ││││││││││ ││ │
|
||||
// 6666555555555544444444443333333333222222222211111111110000000000
|
||||
// 3210987654321098765432109876543210987654321098765432109876543210
|
||||
// │ ││││││ ││││││││││ ││ │
|
||||
.quad 0b0000000000000000000000000000000000000000000000000000000000000000 # 0
|
||||
.quad 0b0000000000001111100110100000000000000000000000001111111111111111 # 8
|
||||
.quad 0b0000000000001111100100100000000000000000000000001111111111111111 #16
|
||||
.quad 0b0000000011001111100110100000000000000000000000001111111111111111 #24
|
||||
.quad 0b0000000011001111100100100000000000000000000000001111111111111111 #32
|
||||
.quad 0b0000000010101111100110110000000000000000000000001111111111111111 #40
|
||||
.quad 0b0000000010101111100100110000000000000000000000001111111111111111 #48
|
||||
.tssdescstub _tss #56,64
|
||||
2:
|
||||
.endobj _gdt,global,hidden
|
||||
|
||||
/*─────────────────────────────────────────────────────────────────────────────╗
|
||||
│ αcτµαlly pδrταblε εxεcµταblε § real mode │
|
||||
@@ -1545,7 +1187,6 @@ _gdtlo = .-GDT_LEGACY_DATA
|
||||
the default mode of operation on modern cpus */
|
||||
|
||||
realmodeloader:
|
||||
call lhinit
|
||||
call rlinit
|
||||
call sinit4
|
||||
.optfn _start16
|
||||
@@ -1553,25 +1194,6 @@ realmodeloader:
|
||||
call longmodeloader
|
||||
.endfn realmodeloader
|
||||
|
||||
// Prepares to later load parts of the program that are not loaded yet.
|
||||
//
|
||||
// @param al next sector number
|
||||
// @param cx next cylinder number
|
||||
// @param dh next head number
|
||||
// @param dl drive number
|
||||
// @clob ax, cx, es, di
|
||||
lhinit: cmp $0x40,%dl
|
||||
je 9f
|
||||
pushpop 0,%es
|
||||
mov $mm+"struct mman::pc_drive_next_sector",%di
|
||||
cld
|
||||
stosb #→ pc_drive_next_sector
|
||||
xchg %ax,%cx
|
||||
stosw #→ pc_drive_next_cylinder
|
||||
mov %dh,%al
|
||||
stosb #→ pc_drive_next_head
|
||||
9: ret
|
||||
|
||||
.section .sort.text.real.init.1,"ax",@progbits
|
||||
.type rlinit,@function
|
||||
rlinit: .previous/*
|
||||
@@ -1632,8 +1254,6 @@ longmodeloader:
|
||||
call lcheck
|
||||
call a20
|
||||
call e820
|
||||
call cpyhi
|
||||
call loadhi
|
||||
call pinit
|
||||
call golong
|
||||
.endfn longmodeloader
|
||||
@@ -1776,88 +1396,10 @@ a20: cli
|
||||
5: ret
|
||||
.endfn a20
|
||||
|
||||
// Copies program pages loaded into base memory, to extended memory.
|
||||
//
|
||||
// @clob esi, edi
|
||||
cpyhi: push %es
|
||||
movpp %ds,%es
|
||||
call unreal
|
||||
mov $IMAGE_BASE_REAL,%esi
|
||||
mov $IMAGE_BASE_PHYSICAL,%edi
|
||||
mov $v_ape_realdwords,%ecx
|
||||
cld
|
||||
rep movsl %ds:(%esi),%es:(%edi)
|
||||
sti
|
||||
pop %es
|
||||
ret
|
||||
.endfn cpyhi
|
||||
|
||||
// Disables interrupts and switches to "unreal mode".
|
||||
//
|
||||
// @return ds, es have same base addresses as before but can access
|
||||
// 4 GiB of memory
|
||||
// @clob eax
|
||||
unreal: push %ds
|
||||
push %es
|
||||
cli
|
||||
lgdt REAL(_gdtrlo)
|
||||
mov %cr0,%eax
|
||||
or $CR0_PE,%al
|
||||
mov %eax,%cr0
|
||||
jmp 0f
|
||||
0: pushpop GDT_LEGACY_DATA,%ds
|
||||
movpp %ds,%es
|
||||
and $~CR0_PE,%al
|
||||
mov %eax,%cr0
|
||||
jmp 1f
|
||||
1: pop %es
|
||||
pop %ds
|
||||
ret
|
||||
|
||||
// Reads any remaining program pages into memory which have not yet
|
||||
// been read by the boot sector.
|
||||
//
|
||||
// @clob eax, ecx, dx, esi, edi, bp
|
||||
loadhi: mov $v_ape_highsectors,%bp
|
||||
test %bp,%bp
|
||||
jz 9f
|
||||
mov $mm+"struct mman::pc_drive",%si
|
||||
cld
|
||||
lodsb #← pc_drive
|
||||
xchg %ax,%dx
|
||||
lodsw
|
||||
lodsb #← pc_drive_next_sector
|
||||
test %al,%al
|
||||
jz 9f
|
||||
xchg %ax,%cx
|
||||
lodsw #← pc_drive_next_cylinder
|
||||
xchg %ax,%cx
|
||||
mov (%si),%dh #← pc_drive_next_head
|
||||
push %es
|
||||
#define SEG 0x79000
|
||||
mov $IMAGE_BASE_PHYSICAL+v_ape_realbytes-SEG,%edi
|
||||
push $SEG>>4
|
||||
pop %es
|
||||
0: call pcread
|
||||
push %ax
|
||||
call unreal
|
||||
pop %ax
|
||||
push %cx
|
||||
xor %esi,%esi
|
||||
xor %ecx,%ecx
|
||||
mov $512/4,%cl
|
||||
cld
|
||||
rep movsl %es:(%esi),%es:(%edi)
|
||||
sti
|
||||
pop %cx
|
||||
dec %bp
|
||||
jnz 0b
|
||||
pop %es
|
||||
9: ret
|
||||
|
||||
// Initializes long mode paging.
|
||||
pinit: push %ds
|
||||
push %es
|
||||
#define SEG 0x79000
|
||||
mov $SEG>>4,%ax
|
||||
mov %ax,%ds
|
||||
mov %ax,%es
|
||||
@@ -1898,7 +1440,7 @@ golong: cli
|
||||
rdmsr
|
||||
or $EFER_LME|EFER_SCE|EFER_NXE,%eax
|
||||
wrmsr
|
||||
lgdt REAL(_gdtrlo)
|
||||
lgdt REAL(_gdtrphy)
|
||||
mov %cr0,%eax
|
||||
or $CR0_PE|CR0_PG|CR0_MP,%eax
|
||||
and $~CR0_EM,%eax
|
||||
@@ -1908,9 +1450,7 @@ golong: cli
|
||||
|
||||
// Long mode is long.
|
||||
.code64
|
||||
long: movabs $BANE+PHYSICAL(0f),%rax
|
||||
jmp *%rax
|
||||
0: xor %eax,%eax
|
||||
long: xor %eax,%eax
|
||||
mov $GDT_LONG_DATA,%al
|
||||
mov %eax,%ds
|
||||
mov %eax,%ss
|
||||
@@ -1918,16 +1458,18 @@ long: movabs $BANE+PHYSICAL(0f),%rax
|
||||
mov %eax,%fs
|
||||
mov %eax,%gs
|
||||
mov $0x80000,%esp
|
||||
mov $GDT_LONG_TSS,%al
|
||||
ltr %ax
|
||||
xor %r12d,%r12d
|
||||
xor %r13d,%r13d
|
||||
xor %r14d,%r14d
|
||||
xor %r15d,%r15d
|
||||
xor %ebx,%ebx
|
||||
xor %ebp,%ebp
|
||||
push %rbp
|
||||
mov $mm,%rdi
|
||||
mov %cr3,%rsi
|
||||
mov $IMAGE_BASE_PHYSICAL,%edx
|
||||
lea v_ape_allbytes(%rdx),%ecx
|
||||
mov $IMAGE_BASE_REAL,%edx
|
||||
call __map_phdrs
|
||||
push $0x037f
|
||||
fldcw (%rsp)
|
||||
@@ -2013,25 +1555,21 @@ kernel: movabs $ape_stack_vaddr,%rsp
|
||||
.byte 0x0f,0x1f,0207 # nop rdi binbase
|
||||
.long (IMAGE_BASE_VIRTUAL-IMAGE_BASE_REAL)/512
|
||||
#endif
|
||||
movabs $BANE+mm,%rdi
|
||||
mov $0x79000,%esi
|
||||
mov $0x7f000,%edx
|
||||
call __reclaim_boot_pages
|
||||
push $_HOSTMETAL # sets __hostos in crt.S
|
||||
pop %rcx
|
||||
pushq .Lenv0(%rip) # envp[0][0]
|
||||
push $0
|
||||
mov %rsp,%rbp
|
||||
pushq .Largv0+8(%rip) # argv[0][8]
|
||||
pushq .Largv0(%rip) # argv[0][0]
|
||||
mov %rsp,%rax
|
||||
mov .Lenv0(%rip),%rax
|
||||
mov %rax,(%rbp) # envp[0][0]
|
||||
push $0 # argv[0][0]
|
||||
push $0 # auxv[1][1]
|
||||
push $0 # auxv[1][0]
|
||||
push %rax # auxv[0][1]
|
||||
push %rbp # auxv[0][1]
|
||||
push $31 # auxv[0][0] AT_EXECFN
|
||||
push $0 # envp[1]
|
||||
push %rbp # envp[0]
|
||||
push $.Lenv0 # envp[0]
|
||||
push $0 # argv[1]
|
||||
push %rax # argv[0]
|
||||
push %rbp # argv[0]
|
||||
push $1 # argc
|
||||
xor %ebp,%ebp
|
||||
xor %eax,%eax
|
||||
@@ -2047,9 +1585,6 @@ kernel: movabs $ape_stack_vaddr,%rsp
|
||||
|
||||
.rodata
|
||||
.Lenv0: .asciz "METAL=1"
|
||||
.Largv0:
|
||||
.asciz APE_COM_NAME
|
||||
.org .Largv0+16
|
||||
.previous
|
||||
|
||||
#endif /* SupportsMetal() */
|
||||
@@ -2062,7 +1597,6 @@ kernel: movabs $ape_stack_vaddr,%rsp
|
||||
.ldsvar _end
|
||||
.ldsvar _etext
|
||||
.ldsvar v_ape_realsectors
|
||||
.ldsvar v_ape_realbytes
|
||||
.ldsvar v_ape_highsectors
|
||||
.ldsvar ape_idata_ro
|
||||
.ldsvar ape_pad_rodata
|
||||
@@ -2156,77 +1690,5 @@ __bss_start:
|
||||
__bss_end:
|
||||
.previous
|
||||
|
||||
.section .blink,"a",@progbits
|
||||
.globl blink_aarch64_size
|
||||
blink_aarch64:
|
||||
.incbin "ape/blink-aarch64.gz"
|
||||
.endobj blink_aarch64,globl
|
||||
blink_aarch64_size = . - blink_aarch64
|
||||
.previous
|
||||
|
||||
.section .blink,"a",@progbits
|
||||
.globl blink_darwin_arm64_size
|
||||
blink_darwin_arm64:
|
||||
.incbin "ape/blink-darwin-arm64.gz"
|
||||
.endobj blink_darwin_arm64,globl
|
||||
blink_darwin_arm64_size = . - blink_darwin_arm64
|
||||
.previous
|
||||
|
||||
.section .blink,"a",@progbits
|
||||
.globl blink_arm_size
|
||||
blink_arm:
|
||||
.incbin "ape/blink-arm.gz"
|
||||
.endobj blink_arm,globl
|
||||
blink_arm_size = . - blink_arm
|
||||
.previous
|
||||
|
||||
.section .blink,"a",@progbits
|
||||
.globl blink_i486_size
|
||||
blink_i486:
|
||||
.incbin "ape/blink-i486.gz"
|
||||
.endobj blink_i486,globl
|
||||
blink_i486_size = . - blink_i486
|
||||
.previous
|
||||
|
||||
.section .blink,"a",@progbits
|
||||
.globl blink_riscv64_size
|
||||
blink_riscv64:
|
||||
.incbin "ape/blink-riscv64.gz"
|
||||
.endobj blink_riscv64,globl
|
||||
blink_riscv64_size = . - blink_riscv64
|
||||
.previous
|
||||
|
||||
.section .blink,"a",@progbits
|
||||
.globl blink_mipsel_size
|
||||
blink_mipsel:
|
||||
.incbin "ape/blink-mipsel.gz"
|
||||
.endobj blink_mipsel,globl
|
||||
blink_mipsel_size = . - blink_mipsel
|
||||
.previous
|
||||
|
||||
.section .blink,"a",@progbits
|
||||
.globl blink_powerpc64le_size
|
||||
blink_powerpc64le:
|
||||
.incbin "ape/blink-powerpc64le.gz"
|
||||
.endobj blink_powerpc64le,globl
|
||||
blink_powerpc64le_size = . - blink_powerpc64le
|
||||
.previous
|
||||
|
||||
.section .blink,"a",@progbits
|
||||
.globl blink_powerpc_size
|
||||
blink_powerpc:
|
||||
.incbin "ape/blink-powerpc.gz"
|
||||
.endobj blink_powerpc,globl
|
||||
blink_powerpc_size = . - blink_powerpc
|
||||
.previous
|
||||
|
||||
.section .blink,"a",@progbits
|
||||
.globl blink_s390x_size
|
||||
blink_s390x:
|
||||
.incbin "ape/blink-s390x.gz"
|
||||
.endobj blink_s390x,globl
|
||||
blink_s390x_size = . - blink_s390x
|
||||
.previous
|
||||
|
||||
.end
|
||||
|
||||
+32
-236
@@ -216,8 +216,6 @@ SECTIONS {
|
||||
KEEP(*(.elf.phdrs))
|
||||
HIDDEN(ape_phdrs_end = .);
|
||||
|
||||
KEEP(*(.emush))
|
||||
|
||||
/* OpenBSD */
|
||||
. = ALIGN(__SIZEOF_POINTER__);
|
||||
HIDDEN(ape_note = .);
|
||||
@@ -275,7 +273,6 @@ SECTIONS {
|
||||
KEEP(*(.textwindowsprologue))
|
||||
*(.text.windows)
|
||||
KEEP(*(.textwindowsepilogue))
|
||||
KEEP(*(.blink))
|
||||
*(SORT_BY_ALIGNMENT(.text.modernity))
|
||||
*(SORT_BY_ALIGNMENT(.text.modernity.*))
|
||||
*(SORT_BY_ALIGNMENT(.text.hot))
|
||||
@@ -352,29 +349,8 @@ SECTIONS {
|
||||
HIDDEN(_etext = .);
|
||||
PROVIDE_HIDDEN(etext = .);
|
||||
/*END: Read Only Data (only needed for initialization) */
|
||||
} :Rom
|
||||
|
||||
/* initialization image for thread-local storage, this is copied */
|
||||
/* out to actual TLS areas at runtime, so just make it read-only */
|
||||
.tdata . : {
|
||||
_tdata_start = .;
|
||||
*(SORT_BY_ALIGNMENT(.tdata))
|
||||
*(SORT_BY_ALIGNMENT(.tdata.*))
|
||||
_tdata_end = .;
|
||||
. = ALIGN(PAGESIZE);
|
||||
} :Tls :Rom
|
||||
/*END: Read Only Data */
|
||||
|
||||
/* this only tells the linker about the layout of uninitialized */
|
||||
/* TLS data, and does not advance the linker's location counter */
|
||||
.tbss . : {
|
||||
_tbss_start = .;
|
||||
*(SORT_BY_ALIGNMENT(.tbss))
|
||||
*(SORT_BY_ALIGNMENT(.tbss.*))
|
||||
. = ALIGN(TLS_ALIGNMENT);
|
||||
/* the %fs register is based on this location */
|
||||
_tbss_end = .;
|
||||
} :Tls
|
||||
} :Rom
|
||||
|
||||
.data ALIGN(PAGESIZE) : {
|
||||
/*BEGIN: Read/Write Data */
|
||||
@@ -409,7 +385,26 @@ SECTIONS {
|
||||
. = ALIGN(PAGESIZE);
|
||||
} :Ram
|
||||
|
||||
.tdata . : {
|
||||
_tdata_start = .;
|
||||
*(SORT_BY_ALIGNMENT(.tdata))
|
||||
*(SORT_BY_ALIGNMENT(.tdata.*))
|
||||
_tdata_end = .;
|
||||
. = ALIGN(PAGESIZE);
|
||||
} :Tls :Ram
|
||||
|
||||
/*END: file content that's loaded by o/s */
|
||||
/*BEGIN: bss memory void */
|
||||
|
||||
.tbss . : {
|
||||
_tbss_start = .;
|
||||
*(SORT_BY_ALIGNMENT(.tbss))
|
||||
*(SORT_BY_ALIGNMENT(.tbss.*))
|
||||
. = ALIGN(TLS_ALIGNMENT);
|
||||
/* the %fs register is based on this location */
|
||||
_tbss_end = .;
|
||||
} :Tls
|
||||
|
||||
/*END: file content */
|
||||
/*BEGIN: bss memory that's addressable */
|
||||
|
||||
@@ -514,7 +509,7 @@ HIDDEN(ape_rom_rva = RVA(ape_rom_vaddr));
|
||||
HIDDEN(ape_ram_offset = ape_rom_offset + ape_rom_filesz);
|
||||
HIDDEN(ape_ram_vaddr = ADDR(.data));
|
||||
HIDDEN(ape_ram_paddr = LOADADDR(.data));
|
||||
HIDDEN(ape_ram_filesz = SIZEOF(.data));
|
||||
HIDDEN(ape_ram_filesz = SIZEOF(.data) + SIZEOF(.tdata));
|
||||
HIDDEN(ape_ram_memsz = ADDR(.bss) + SIZEOF(.bss) - ape_ram_vaddr);
|
||||
HIDDEN(ape_ram_align = PAGESIZE);
|
||||
HIDDEN(ape_ram_rva = RVA(ape_ram_vaddr));
|
||||
@@ -538,16 +533,16 @@ HIDDEN(ape_note_align = __SIZEOF_POINTER__);
|
||||
HIDDEN(ape_text_offset = ape_rom_offset + LOADADDR(.text) - ape_rom_paddr);
|
||||
HIDDEN(ape_text_paddr = LOADADDR(.text));
|
||||
HIDDEN(ape_text_vaddr = ADDR(.text));
|
||||
HIDDEN(ape_text_filesz = SIZEOF(.text) + SIZEOF(.tdata));
|
||||
HIDDEN(ape_text_memsz = SIZEOF(.text) + SIZEOF(.tdata));
|
||||
HIDDEN(ape_text_filesz = SIZEOF(.text));
|
||||
HIDDEN(ape_text_memsz = SIZEOF(.text));
|
||||
HIDDEN(ape_text_align = PAGESIZE);
|
||||
HIDDEN(ape_text_rva = RVA(ape_text_vaddr));
|
||||
|
||||
HIDDEN(ape_data_offset = ape_ram_offset + LOADADDR(.data) - ape_ram_paddr);
|
||||
HIDDEN(ape_data_paddr = LOADADDR(.data));
|
||||
HIDDEN(ape_data_vaddr = ADDR(.data));
|
||||
HIDDEN(ape_data_filesz = SIZEOF(.data));
|
||||
HIDDEN(ape_data_memsz = SIZEOF(.data));
|
||||
HIDDEN(ape_data_filesz = SIZEOF(.data) + SIZEOF(.tdata));
|
||||
HIDDEN(ape_data_memsz = SIZEOF(.data) + SIZEOF(.tdata));
|
||||
HIDDEN(ape_data_align = PAGESIZE);
|
||||
HIDDEN(ape_data_rva = RVA(ape_data_vaddr));
|
||||
|
||||
@@ -567,212 +562,13 @@ SHSTUB2(ape_loader_dd_count,
|
||||
? ROUNDUP(ape_loader_end - ape_loader, PAGESIZE) / 64
|
||||
: 0);
|
||||
|
||||
HIDDEN(blink_aarch64_b0 = RVA(blink_aarch64) % 10 + 48);
|
||||
HIDDEN(blink_aarch64_b1 = RVA(blink_aarch64) < 10 ? 32 : RVA(blink_aarch64) / 10 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_b2 = RVA(blink_aarch64) < 100 ? 32 : RVA(blink_aarch64) / 100 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_b3 = RVA(blink_aarch64) < 1000 ? 32 : RVA(blink_aarch64) / 1000 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_b4 = RVA(blink_aarch64) < 10000 ? 32 : RVA(blink_aarch64) / 10000 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_b5 = RVA(blink_aarch64) < 100000 ? 32 : RVA(blink_aarch64) / 100000 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_b6 = RVA(blink_aarch64) < 1000000 ? 32 : RVA(blink_aarch64) / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_b7 = RVA(blink_aarch64) < 10000000 ? 32 : RVA(blink_aarch64) / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_b8 = RVA(blink_aarch64) < 100000000 ? 32 : RVA(blink_aarch64) / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_b9 = RVA(blink_aarch64) < 1000000000 ? 32 : RVA(blink_aarch64) / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_aarch64_size_b0 = blink_aarch64_size % 10 + 48);
|
||||
HIDDEN(blink_aarch64_size_b1 = blink_aarch64_size < 10 ? 32 : blink_aarch64_size / 10 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_size_b2 = blink_aarch64_size < 100 ? 32 : blink_aarch64_size / 100 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_size_b3 = blink_aarch64_size < 1000 ? 32 : blink_aarch64_size / 1000 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_size_b4 = blink_aarch64_size < 10000 ? 32 : blink_aarch64_size / 10000 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_size_b5 = blink_aarch64_size < 100000 ? 32 : blink_aarch64_size / 100000 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_size_b6 = blink_aarch64_size < 1000000 ? 32 : blink_aarch64_size / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_size_b7 = blink_aarch64_size < 10000000 ? 32 : blink_aarch64_size / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_size_b8 = blink_aarch64_size < 100000000 ? 32 : blink_aarch64_size / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_aarch64_size_b9 = blink_aarch64_size < 1000000000 ? 32 : blink_aarch64_size / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_darwin_arm64_b0 = RVA(blink_darwin_arm64) % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_b1 = RVA(blink_darwin_arm64) < 10 ? 32 : RVA(blink_darwin_arm64) / 10 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_b2 = RVA(blink_darwin_arm64) < 100 ? 32 : RVA(blink_darwin_arm64) / 100 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_b3 = RVA(blink_darwin_arm64) < 1000 ? 32 : RVA(blink_darwin_arm64) / 1000 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_b4 = RVA(blink_darwin_arm64) < 10000 ? 32 : RVA(blink_darwin_arm64) / 10000 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_b5 = RVA(blink_darwin_arm64) < 100000 ? 32 : RVA(blink_darwin_arm64) / 100000 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_b6 = RVA(blink_darwin_arm64) < 1000000 ? 32 : RVA(blink_darwin_arm64) / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_b7 = RVA(blink_darwin_arm64) < 10000000 ? 32 : RVA(blink_darwin_arm64) / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_b8 = RVA(blink_darwin_arm64) < 100000000 ? 32 : RVA(blink_darwin_arm64) / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_b9 = RVA(blink_darwin_arm64) < 1000000000 ? 32 : RVA(blink_darwin_arm64) / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_darwin_arm64_size_b0 = blink_darwin_arm64_size % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_size_b1 = blink_darwin_arm64_size < 10 ? 32 : blink_darwin_arm64_size / 10 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_size_b2 = blink_darwin_arm64_size < 100 ? 32 : blink_darwin_arm64_size / 100 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_size_b3 = blink_darwin_arm64_size < 1000 ? 32 : blink_darwin_arm64_size / 1000 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_size_b4 = blink_darwin_arm64_size < 10000 ? 32 : blink_darwin_arm64_size / 10000 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_size_b5 = blink_darwin_arm64_size < 100000 ? 32 : blink_darwin_arm64_size / 100000 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_size_b6 = blink_darwin_arm64_size < 1000000 ? 32 : blink_darwin_arm64_size / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_size_b7 = blink_darwin_arm64_size < 10000000 ? 32 : blink_darwin_arm64_size / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_size_b8 = blink_darwin_arm64_size < 100000000 ? 32 : blink_darwin_arm64_size / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_darwin_arm64_size_b9 = blink_darwin_arm64_size < 1000000000 ? 32 : blink_darwin_arm64_size / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_arm_b0 = RVA(blink_arm) % 10 + 48);
|
||||
HIDDEN(blink_arm_b1 = RVA(blink_arm) < 10 ? 32 : RVA(blink_arm) / 10 % 10 + 48);
|
||||
HIDDEN(blink_arm_b2 = RVA(blink_arm) < 100 ? 32 : RVA(blink_arm) / 100 % 10 + 48);
|
||||
HIDDEN(blink_arm_b3 = RVA(blink_arm) < 1000 ? 32 : RVA(blink_arm) / 1000 % 10 + 48);
|
||||
HIDDEN(blink_arm_b4 = RVA(blink_arm) < 10000 ? 32 : RVA(blink_arm) / 10000 % 10 + 48);
|
||||
HIDDEN(blink_arm_b5 = RVA(blink_arm) < 100000 ? 32 : RVA(blink_arm) / 100000 % 10 + 48);
|
||||
HIDDEN(blink_arm_b6 = RVA(blink_arm) < 1000000 ? 32 : RVA(blink_arm) / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_arm_b7 = RVA(blink_arm) < 10000000 ? 32 : RVA(blink_arm) / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_arm_b8 = RVA(blink_arm) < 100000000 ? 32 : RVA(blink_arm) / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_arm_b9 = RVA(blink_arm) < 1000000000 ? 32 : RVA(blink_arm) / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_arm_size_b0 = blink_arm_size % 10 + 48);
|
||||
HIDDEN(blink_arm_size_b1 = blink_arm_size < 10 ? 32 : blink_arm_size / 10 % 10 + 48);
|
||||
HIDDEN(blink_arm_size_b2 = blink_arm_size < 100 ? 32 : blink_arm_size / 100 % 10 + 48);
|
||||
HIDDEN(blink_arm_size_b3 = blink_arm_size < 1000 ? 32 : blink_arm_size / 1000 % 10 + 48);
|
||||
HIDDEN(blink_arm_size_b4 = blink_arm_size < 10000 ? 32 : blink_arm_size / 10000 % 10 + 48);
|
||||
HIDDEN(blink_arm_size_b5 = blink_arm_size < 100000 ? 32 : blink_arm_size / 100000 % 10 + 48);
|
||||
HIDDEN(blink_arm_size_b6 = blink_arm_size < 1000000 ? 32 : blink_arm_size / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_arm_size_b7 = blink_arm_size < 10000000 ? 32 : blink_arm_size / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_arm_size_b8 = blink_arm_size < 100000000 ? 32 : blink_arm_size / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_arm_size_b9 = blink_arm_size < 1000000000 ? 32 : blink_arm_size / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_i486_b0 = RVA(blink_i486) % 10 + 48);
|
||||
HIDDEN(blink_i486_b1 = RVA(blink_i486) < 10 ? 32 : RVA(blink_i486) / 10 % 10 + 48);
|
||||
HIDDEN(blink_i486_b2 = RVA(blink_i486) < 100 ? 32 : RVA(blink_i486) / 100 % 10 + 48);
|
||||
HIDDEN(blink_i486_b3 = RVA(blink_i486) < 1000 ? 32 : RVA(blink_i486) / 1000 % 10 + 48);
|
||||
HIDDEN(blink_i486_b4 = RVA(blink_i486) < 10000 ? 32 : RVA(blink_i486) / 10000 % 10 + 48);
|
||||
HIDDEN(blink_i486_b5 = RVA(blink_i486) < 100000 ? 32 : RVA(blink_i486) / 100000 % 10 + 48);
|
||||
HIDDEN(blink_i486_b6 = RVA(blink_i486) < 1000000 ? 32 : RVA(blink_i486) / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_i486_b7 = RVA(blink_i486) < 10000000 ? 32 : RVA(blink_i486) / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_i486_b8 = RVA(blink_i486) < 100000000 ? 32 : RVA(blink_i486) / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_i486_b9 = RVA(blink_i486) < 1000000000 ? 32 : RVA(blink_i486) / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_i486_size_b0 = blink_i486_size % 10 + 48);
|
||||
HIDDEN(blink_i486_size_b1 = blink_i486_size < 10 ? 32 : blink_i486_size / 10 % 10 + 48);
|
||||
HIDDEN(blink_i486_size_b2 = blink_i486_size < 100 ? 32 : blink_i486_size / 100 % 10 + 48);
|
||||
HIDDEN(blink_i486_size_b3 = blink_i486_size < 1000 ? 32 : blink_i486_size / 1000 % 10 + 48);
|
||||
HIDDEN(blink_i486_size_b4 = blink_i486_size < 10000 ? 32 : blink_i486_size / 10000 % 10 + 48);
|
||||
HIDDEN(blink_i486_size_b5 = blink_i486_size < 100000 ? 32 : blink_i486_size / 100000 % 10 + 48);
|
||||
HIDDEN(blink_i486_size_b6 = blink_i486_size < 1000000 ? 32 : blink_i486_size / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_i486_size_b7 = blink_i486_size < 10000000 ? 32 : blink_i486_size / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_i486_size_b8 = blink_i486_size < 100000000 ? 32 : blink_i486_size / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_i486_size_b9 = blink_i486_size < 1000000000 ? 32 : blink_i486_size / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_riscv64_b0 = RVA(blink_riscv64) % 10 + 48);
|
||||
HIDDEN(blink_riscv64_b1 = RVA(blink_riscv64) < 10 ? 32 : RVA(blink_riscv64) / 10 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_b2 = RVA(blink_riscv64) < 100 ? 32 : RVA(blink_riscv64) / 100 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_b3 = RVA(blink_riscv64) < 1000 ? 32 : RVA(blink_riscv64) / 1000 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_b4 = RVA(blink_riscv64) < 10000 ? 32 : RVA(blink_riscv64) / 10000 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_b5 = RVA(blink_riscv64) < 100000 ? 32 : RVA(blink_riscv64) / 100000 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_b6 = RVA(blink_riscv64) < 1000000 ? 32 : RVA(blink_riscv64) / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_b7 = RVA(blink_riscv64) < 10000000 ? 32 : RVA(blink_riscv64) / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_b8 = RVA(blink_riscv64) < 100000000 ? 32 : RVA(blink_riscv64) / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_b9 = RVA(blink_riscv64) < 1000000000 ? 32 : RVA(blink_riscv64) / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_riscv64_size_b0 = blink_riscv64_size % 10 + 48);
|
||||
HIDDEN(blink_riscv64_size_b1 = blink_riscv64_size < 10 ? 32 : blink_riscv64_size / 10 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_size_b2 = blink_riscv64_size < 100 ? 32 : blink_riscv64_size / 100 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_size_b3 = blink_riscv64_size < 1000 ? 32 : blink_riscv64_size / 1000 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_size_b4 = blink_riscv64_size < 10000 ? 32 : blink_riscv64_size / 10000 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_size_b5 = blink_riscv64_size < 100000 ? 32 : blink_riscv64_size / 100000 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_size_b6 = blink_riscv64_size < 1000000 ? 32 : blink_riscv64_size / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_size_b7 = blink_riscv64_size < 10000000 ? 32 : blink_riscv64_size / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_size_b8 = blink_riscv64_size < 100000000 ? 32 : blink_riscv64_size / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_riscv64_size_b9 = blink_riscv64_size < 1000000000 ? 32 : blink_riscv64_size / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_mipsel_b0 = RVA(blink_mipsel) % 10 + 48);
|
||||
HIDDEN(blink_mipsel_b1 = RVA(blink_mipsel) < 10 ? 32 : RVA(blink_mipsel) / 10 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_b2 = RVA(blink_mipsel) < 100 ? 32 : RVA(blink_mipsel) / 100 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_b3 = RVA(blink_mipsel) < 1000 ? 32 : RVA(blink_mipsel) / 1000 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_b4 = RVA(blink_mipsel) < 10000 ? 32 : RVA(blink_mipsel) / 10000 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_b5 = RVA(blink_mipsel) < 100000 ? 32 : RVA(blink_mipsel) / 100000 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_b6 = RVA(blink_mipsel) < 1000000 ? 32 : RVA(blink_mipsel) / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_b7 = RVA(blink_mipsel) < 10000000 ? 32 : RVA(blink_mipsel) / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_b8 = RVA(blink_mipsel) < 100000000 ? 32 : RVA(blink_mipsel) / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_b9 = RVA(blink_mipsel) < 1000000000 ? 32 : RVA(blink_mipsel) / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_mipsel_size_b0 = blink_mipsel_size % 10 + 48);
|
||||
HIDDEN(blink_mipsel_size_b1 = blink_mipsel_size < 10 ? 32 : blink_mipsel_size / 10 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_size_b2 = blink_mipsel_size < 100 ? 32 : blink_mipsel_size / 100 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_size_b3 = blink_mipsel_size < 1000 ? 32 : blink_mipsel_size / 1000 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_size_b4 = blink_mipsel_size < 10000 ? 32 : blink_mipsel_size / 10000 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_size_b5 = blink_mipsel_size < 100000 ? 32 : blink_mipsel_size / 100000 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_size_b6 = blink_mipsel_size < 1000000 ? 32 : blink_mipsel_size / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_size_b7 = blink_mipsel_size < 10000000 ? 32 : blink_mipsel_size / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_size_b8 = blink_mipsel_size < 100000000 ? 32 : blink_mipsel_size / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_mipsel_size_b9 = blink_mipsel_size < 1000000000 ? 32 : blink_mipsel_size / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_powerpc64le_b0 = RVA(blink_powerpc64le) % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_b1 = RVA(blink_powerpc64le) < 10 ? 32 : RVA(blink_powerpc64le) / 10 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_b2 = RVA(blink_powerpc64le) < 100 ? 32 : RVA(blink_powerpc64le) / 100 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_b3 = RVA(blink_powerpc64le) < 1000 ? 32 : RVA(blink_powerpc64le) / 1000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_b4 = RVA(blink_powerpc64le) < 10000 ? 32 : RVA(blink_powerpc64le) / 10000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_b5 = RVA(blink_powerpc64le) < 100000 ? 32 : RVA(blink_powerpc64le) / 100000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_b6 = RVA(blink_powerpc64le) < 1000000 ? 32 : RVA(blink_powerpc64le) / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_b7 = RVA(blink_powerpc64le) < 10000000 ? 32 : RVA(blink_powerpc64le) / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_b8 = RVA(blink_powerpc64le) < 100000000 ? 32 : RVA(blink_powerpc64le) / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_b9 = RVA(blink_powerpc64le) < 1000000000 ? 32 : RVA(blink_powerpc64le) / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_powerpc64le_size_b0 = blink_powerpc64le_size % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_size_b1 = blink_powerpc64le_size < 10 ? 32 : blink_powerpc64le_size / 10 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_size_b2 = blink_powerpc64le_size < 100 ? 32 : blink_powerpc64le_size / 100 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_size_b3 = blink_powerpc64le_size < 1000 ? 32 : blink_powerpc64le_size / 1000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_size_b4 = blink_powerpc64le_size < 10000 ? 32 : blink_powerpc64le_size / 10000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_size_b5 = blink_powerpc64le_size < 100000 ? 32 : blink_powerpc64le_size / 100000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_size_b6 = blink_powerpc64le_size < 1000000 ? 32 : blink_powerpc64le_size / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_size_b7 = blink_powerpc64le_size < 10000000 ? 32 : blink_powerpc64le_size / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_size_b8 = blink_powerpc64le_size < 100000000 ? 32 : blink_powerpc64le_size / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc64le_size_b9 = blink_powerpc64le_size < 1000000000 ? 32 : blink_powerpc64le_size / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_powerpc_b0 = RVA(blink_powerpc) % 10 + 48);
|
||||
HIDDEN(blink_powerpc_b1 = RVA(blink_powerpc) < 10 ? 32 : RVA(blink_powerpc) / 10 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_b2 = RVA(blink_powerpc) < 100 ? 32 : RVA(blink_powerpc) / 100 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_b3 = RVA(blink_powerpc) < 1000 ? 32 : RVA(blink_powerpc) / 1000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_b4 = RVA(blink_powerpc) < 10000 ? 32 : RVA(blink_powerpc) / 10000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_b5 = RVA(blink_powerpc) < 100000 ? 32 : RVA(blink_powerpc) / 100000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_b6 = RVA(blink_powerpc) < 1000000 ? 32 : RVA(blink_powerpc) / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_b7 = RVA(blink_powerpc) < 10000000 ? 32 : RVA(blink_powerpc) / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_b8 = RVA(blink_powerpc) < 100000000 ? 32 : RVA(blink_powerpc) / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_b9 = RVA(blink_powerpc) < 1000000000 ? 32 : RVA(blink_powerpc) / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_powerpc_size_b0 = blink_powerpc_size % 10 + 48);
|
||||
HIDDEN(blink_powerpc_size_b1 = blink_powerpc_size < 10 ? 32 : blink_powerpc_size / 10 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_size_b2 = blink_powerpc_size < 100 ? 32 : blink_powerpc_size / 100 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_size_b3 = blink_powerpc_size < 1000 ? 32 : blink_powerpc_size / 1000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_size_b4 = blink_powerpc_size < 10000 ? 32 : blink_powerpc_size / 10000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_size_b5 = blink_powerpc_size < 100000 ? 32 : blink_powerpc_size / 100000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_size_b6 = blink_powerpc_size < 1000000 ? 32 : blink_powerpc_size / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_size_b7 = blink_powerpc_size < 10000000 ? 32 : blink_powerpc_size / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_size_b8 = blink_powerpc_size < 100000000 ? 32 : blink_powerpc_size / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_powerpc_size_b9 = blink_powerpc_size < 1000000000 ? 32 : blink_powerpc_size / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_s390x_b0 = RVA(blink_s390x) % 10 + 48);
|
||||
HIDDEN(blink_s390x_b1 = RVA(blink_s390x) < 10 ? 32 : RVA(blink_s390x) / 10 % 10 + 48);
|
||||
HIDDEN(blink_s390x_b2 = RVA(blink_s390x) < 100 ? 32 : RVA(blink_s390x) / 100 % 10 + 48);
|
||||
HIDDEN(blink_s390x_b3 = RVA(blink_s390x) < 1000 ? 32 : RVA(blink_s390x) / 1000 % 10 + 48);
|
||||
HIDDEN(blink_s390x_b4 = RVA(blink_s390x) < 10000 ? 32 : RVA(blink_s390x) / 10000 % 10 + 48);
|
||||
HIDDEN(blink_s390x_b5 = RVA(blink_s390x) < 100000 ? 32 : RVA(blink_s390x) / 100000 % 10 + 48);
|
||||
HIDDEN(blink_s390x_b6 = RVA(blink_s390x) < 1000000 ? 32 : RVA(blink_s390x) / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_s390x_b7 = RVA(blink_s390x) < 10000000 ? 32 : RVA(blink_s390x) / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_s390x_b8 = RVA(blink_s390x) < 100000000 ? 32 : RVA(blink_s390x) / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_s390x_b9 = RVA(blink_s390x) < 1000000000 ? 32 : RVA(blink_s390x) / 1000000000 % 10 + 48);
|
||||
|
||||
HIDDEN(blink_s390x_size_b0 = blink_s390x_size % 10 + 48);
|
||||
HIDDEN(blink_s390x_size_b1 = blink_s390x_size < 10 ? 32 : blink_s390x_size / 10 % 10 + 48);
|
||||
HIDDEN(blink_s390x_size_b2 = blink_s390x_size < 100 ? 32 : blink_s390x_size / 100 % 10 + 48);
|
||||
HIDDEN(blink_s390x_size_b3 = blink_s390x_size < 1000 ? 32 : blink_s390x_size / 1000 % 10 + 48);
|
||||
HIDDEN(blink_s390x_size_b4 = blink_s390x_size < 10000 ? 32 : blink_s390x_size / 10000 % 10 + 48);
|
||||
HIDDEN(blink_s390x_size_b5 = blink_s390x_size < 100000 ? 32 : blink_s390x_size / 100000 % 10 + 48);
|
||||
HIDDEN(blink_s390x_size_b6 = blink_s390x_size < 1000000 ? 32 : blink_s390x_size / 1000000 % 10 + 48);
|
||||
HIDDEN(blink_s390x_size_b7 = blink_s390x_size < 10000000 ? 32 : blink_s390x_size / 10000000 % 10 + 48);
|
||||
HIDDEN(blink_s390x_size_b8 = blink_s390x_size < 100000000 ? 32 : blink_s390x_size / 100000000 % 10 + 48);
|
||||
HIDDEN(blink_s390x_size_b9 = blink_s390x_size < 1000000000 ? 32 : blink_s390x_size / 1000000000 % 10 + 48);
|
||||
|
||||
#if SupportsMetal()
|
||||
HIDDEN(v_ape_realsectors =
|
||||
MIN(0x70000 - IMAGE_BASE_REAL, ROUNDUP(RVA(_ezip), 512)) / 512);
|
||||
HIDDEN(v_ape_realbytes = v_ape_realsectors * 512);
|
||||
HIDDEN(v_ape_realdwords = v_ape_realsectors * (512 / 4));
|
||||
HIDDEN(v_ape_allsectors = ROUNDUP(RVA(_ezip), 512) / 512);
|
||||
HIDDEN(v_ape_allbytes = v_ape_allsectors * 512);
|
||||
HIDDEN(v_ape_highsectors = v_ape_allsectors - v_ape_realsectors);
|
||||
MIN(0x70000 - IMAGE_BASE_REAL,
|
||||
ROUNDUP(RVA(_edata), 512)) / 512);
|
||||
HIDDEN(v_ape_realpages = v_ape_realsectors / (4096 / 512));
|
||||
HIDDEN(v_ape_highsectors =
|
||||
(ROUNDUP(RVA(_edata), 512) / 512) - v_ape_realsectors);
|
||||
TSSDESCSTUB2(_tss, _tss, _tss_end ? _tss_end - _tss - 1 : 0);
|
||||
#endif
|
||||
|
||||
@@ -855,7 +651,7 @@ CHURN(ADDR(.bss));
|
||||
CHURN(_start);
|
||||
CHURN(ape_phdrs);
|
||||
#if SupportsMetal()
|
||||
CHURN(v_ape_allsectors);
|
||||
CHURN(v_ape_realsectors);
|
||||
#endif
|
||||
#if SupportsXnu()
|
||||
CHURN(ape_macho);
|
||||
@@ -919,7 +715,7 @@ ASSERT(IS2POW(ape_stack_memsz),
|
||||
"ape_stack_memsz must be a two power");
|
||||
|
||||
ASSERT(ape_stack_vaddr % ape_stack_memsz == 0,
|
||||
"ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 & -ape_stack_memsz);");
|
||||
"ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 - ape_stack_memsz);");
|
||||
|
||||
ASSERT(ALIGNOF(.tdata) <= TLS_ALIGNMENT && ALIGNOF(.tbss) <= TLS_ALIGNMENT,
|
||||
"_Thread_local _Alignof can't exceed TLS_ALIGNMENT");
|
||||
|
||||
+1
-32
@@ -96,17 +96,6 @@ o/ape/idata.inc: \
|
||||
ape/idata.internal.h \
|
||||
ape/relocations.h
|
||||
|
||||
o/$(MODE)/ape/ape.o: \
|
||||
ape/blink-aarch64.gz \
|
||||
ape/blink-arm.gz \
|
||||
ape/blink-darwin-arm64.gz \
|
||||
ape/blink-i486.gz \
|
||||
ape/blink-mipsel.gz \
|
||||
ape/blink-powerpc.gz \
|
||||
ape/blink-powerpc64le.gz \
|
||||
ape/blink-riscv64.gz \
|
||||
ape/blink-s390x.gz
|
||||
|
||||
o/$(MODE)/ape/ape-no-modify-self.o: \
|
||||
ape/ape.S \
|
||||
ape/macros.internal.h \
|
||||
@@ -118,7 +107,6 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
|
||||
libc/macho.internal.h \
|
||||
libc/macros.internal.h \
|
||||
libc/nexgen32e/uart.internal.h \
|
||||
libc/calls/metalfile.internal.h \
|
||||
libc/nexgen32e/vidya.internal.h \
|
||||
libc/nt/pedef.internal.h \
|
||||
libc/runtime/e820.internal.h \
|
||||
@@ -126,15 +114,6 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
|
||||
libc/runtime/pc.internal.h \
|
||||
libc/runtime/symbolic.h \
|
||||
libc/sysv/consts/prot.h \
|
||||
ape/blink-aarch64.gz \
|
||||
ape/blink-arm.gz \
|
||||
ape/blink-darwin-arm64.gz \
|
||||
ape/blink-i486.gz \
|
||||
ape/blink-mipsel.gz \
|
||||
ape/blink-powerpc.gz \
|
||||
ape/blink-powerpc64le.gz \
|
||||
ape/blink-riscv64.gz \
|
||||
ape/blink-s390x.gz \
|
||||
o/$(MODE)/ape/ape.elf
|
||||
@$(COMPILE) \
|
||||
-AOBJECTIFY.S \
|
||||
@@ -154,23 +133,13 @@ o/$(MODE)/ape/ape-copy-self.o: \
|
||||
libc/macho.internal.h \
|
||||
libc/macros.internal.h \
|
||||
libc/nexgen32e/uart.internal.h \
|
||||
libc/calls/metalfile.internal.h \
|
||||
libc/nexgen32e/vidya.internal.h \
|
||||
libc/nt/pedef.internal.h \
|
||||
libc/runtime/e820.internal.h \
|
||||
libc/runtime/mman.internal.h \
|
||||
libc/runtime/pc.internal.h \
|
||||
libc/runtime/symbolic.h \
|
||||
libc/sysv/consts/prot.h \
|
||||
ape/blink-aarch64.gz \
|
||||
ape/blink-arm.gz \
|
||||
ape/blink-darwin-arm64.gz \
|
||||
ape/blink-i486.gz \
|
||||
ape/blink-mipsel.gz \
|
||||
ape/blink-powerpc.gz \
|
||||
ape/blink-powerpc64le.gz \
|
||||
ape/blink-riscv64.gz \
|
||||
ape/blink-s390x.gz
|
||||
libc/sysv/consts/prot.h
|
||||
@$(COMPILE) \
|
||||
-AOBJECTIFY.S \
|
||||
$(OBJECTIFY.S) \
|
||||
|
||||
+1
-3
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
if [ $UID -eq 0 ]; then
|
||||
SUDO=
|
||||
else
|
||||
SUDO=sudo
|
||||
@@ -97,8 +97,6 @@ if [ x"$(uname -s)" = xLinux ]; then
|
||||
echo you may need to edit configs to persist across reboot >&2
|
||||
echo '$SUDO sh -c "echo '"'"':APE:M::MZqFpD::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
|
||||
$SUDO sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
|
||||
echo '$SUDO sh -c "echo '"'"':APE-jart:M::jartsr::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
|
||||
$SUDO sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
|
||||
echo done >&2
|
||||
|
||||
if [ x"$(cat /proc/sys/fs/binfmt_misc/status)" = xdisabled ]; then
|
||||
|
||||
+6
-8
@@ -8,19 +8,17 @@ fi
|
||||
|
||||
{
|
||||
echo
|
||||
echo "APE Uninstaller intends to run (in pseudo-shell)"
|
||||
echo "APE Uninstaller intends to run"
|
||||
echo
|
||||
echo " sudo echo -1 into /proc/sys/fs/binfmt_misc/APE*"
|
||||
echo " sudo rm -f /usr/bin/ape ~/.ape o/tmp/.ape /tmp/.ape"
|
||||
echo " $SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE'"
|
||||
echo " $SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape /tmp/.ape"
|
||||
echo
|
||||
echo "You may then use ape/apeinstall.sh to reinstall it"
|
||||
echo
|
||||
} >&2
|
||||
|
||||
set -ex
|
||||
for f in /proc/sys/fs/binfmt_misc/APE*; do
|
||||
if [ -f $f ]; then
|
||||
$SUDO sh -c "echo -1 >$f" || exit
|
||||
fi
|
||||
done
|
||||
if [ -f /proc/sys/fs/binfmt_misc/APE ]; then
|
||||
$SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE' || exit
|
||||
fi
|
||||
$SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape o/tmp/ape /tmp/.ape /tmp/ape || exit
|
||||
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,34 +0,0 @@
|
||||
#ifndef COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_
|
||||
#define COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern unsigned char _base[];
|
||||
extern unsigned char _ehead[];
|
||||
extern unsigned char _etext[];
|
||||
extern unsigned char _edata[];
|
||||
extern unsigned char _ezip[];
|
||||
extern unsigned char _end[];
|
||||
extern unsigned char _ereal[];
|
||||
extern unsigned char _tdata_start[];
|
||||
extern unsigned char _tdata_end[];
|
||||
extern unsigned char _tbss_start[];
|
||||
extern unsigned char _tbss_end[];
|
||||
extern unsigned char __privileged_start[];
|
||||
extern unsigned char __privileged_addr[];
|
||||
extern unsigned char __privileged_size[];
|
||||
extern unsigned char __privileged_end[];
|
||||
extern unsigned char __test_start[];
|
||||
extern unsigned char __ro[];
|
||||
extern unsigned char *__relo_start[];
|
||||
extern unsigned char *__relo_end[];
|
||||
extern uint8_t __zip_start[];
|
||||
extern uint8_t __zip_end[];
|
||||
extern uint8_t __data_start[];
|
||||
extern uint8_t __data_end[];
|
||||
extern uint8_t __bss_start[];
|
||||
extern uint8_t __bss_end[];
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_ */
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+6
-27
@@ -29,7 +29,7 @@ endif
|
||||
#
|
||||
ifeq ($(MODE),fastbuild)
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG -DDWARFLESS
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
CONFIG_OFLAGS += -g0
|
||||
CONFIG_LDFLAGS += -S
|
||||
TARGET_ARCH ?= -msse3
|
||||
@@ -125,22 +125,6 @@ TARGET_ARCH ?= -msse3
|
||||
OVERRIDE_CCFLAGS += -fno-pie
|
||||
endif
|
||||
|
||||
# System Five Mode
|
||||
#
|
||||
# - `make MODE=sysv`
|
||||
# - Optimized
|
||||
# - Backtraces
|
||||
# - Debuggable
|
||||
# - Syscall tracing
|
||||
# - Function tracing
|
||||
# - No Windows bloat!
|
||||
#
|
||||
ifeq ($(MODE), sysv)
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O2
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG -DSUPPORT_VECTOR=121
|
||||
TARGET_ARCH ?= -msse3
|
||||
endif
|
||||
|
||||
# Tiny Mode
|
||||
#
|
||||
# - `make MODE=tiny`
|
||||
@@ -167,8 +151,7 @@ CONFIG_CCFLAGS += \
|
||||
-fschedule-insns2 \
|
||||
-fomit-frame-pointer \
|
||||
-momit-leaf-frame-pointer \
|
||||
-foptimize-sibling-calls \
|
||||
-DDWARFLESS
|
||||
-foptimize-sibling-calls
|
||||
CONFIG_OFLAGS += \
|
||||
-g0
|
||||
CONFIG_LDFLAGS += \
|
||||
@@ -198,8 +181,7 @@ CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
-DNDEBUG \
|
||||
-DTRUSTWORTHY \
|
||||
-DSUPPORT_VECTOR=1 \
|
||||
-DDWARFLESS
|
||||
-DSUPPORT_VECTOR=1
|
||||
DEFAULT_COPTS += \
|
||||
-mred-zone
|
||||
CONFIG_OFLAGS += \
|
||||
@@ -235,8 +217,7 @@ CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
-DNDEBUG \
|
||||
-DTRUSTWORTHY \
|
||||
-DSUPPORT_VECTOR=113 \
|
||||
-DDWARFLESS
|
||||
-DSUPPORT_VECTOR=113
|
||||
DEFAULT_COPTS += \
|
||||
-mred-zone
|
||||
CONFIG_OFLAGS += \
|
||||
@@ -271,8 +252,7 @@ CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
-DNDEBUG \
|
||||
-DTRUSTWORTHY \
|
||||
-DSUPPORT_VECTOR=121 \
|
||||
-DDWARFLESS
|
||||
-DSUPPORT_VECTOR=121
|
||||
DEFAULT_COPTS += \
|
||||
-mred-zone
|
||||
CONFIG_CCFLAGS += \
|
||||
@@ -307,8 +287,7 @@ CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
-DNDEBUG \
|
||||
-DTRUSTWORTHY \
|
||||
-DSUPPORT_VECTOR=251 \
|
||||
-DDWARFLESS
|
||||
-DSUPPORT_VECTOR=251
|
||||
CONFIG_CCFLAGS += \
|
||||
-Os \
|
||||
-fno-align-functions \
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
LC_ALL = C
|
||||
SOURCE_DATE_EPOCH = 0
|
||||
|
||||
TAGS ?= /usr/bin/ctags # emacs source builds or something breaks it
|
||||
ARFLAGS = rcsD
|
||||
ZFLAGS ?=
|
||||
XARGS ?= xargs -P4 -rs8000
|
||||
|
||||
+1
-4
@@ -43,9 +43,6 @@
|
||||
# '(progn
|
||||
# (add-hook 'c-mode-common-hook 'jart-c-mode-common-hook)))
|
||||
|
||||
TAGS="$1"
|
||||
shift
|
||||
|
||||
# ctags doesn't understand atomics, e.g.
|
||||
# extern char **environ;
|
||||
set -- --regex-c='/_Atomic(\([^)]*\))/\1/b' "$@"
|
||||
@@ -66,7 +63,7 @@ set -- --regex-c='/^extern [^(]*(\*const \([^)]*\))(/\1/b' "$@"
|
||||
# struct WorstSoftwareEver;
|
||||
set -- --regex-c='/^struct.*;$/uehocruehcroue/b' "$@"
|
||||
|
||||
exec $TAGS \
|
||||
exec ${TAGS:-ctags} \
|
||||
-e \
|
||||
--langmap=c:.c.h \
|
||||
--exclude=libc/nt/struct/imagefileheader.internal.h \
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
@@ -59,15 +59,9 @@
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (!IsAsan()) {
|
||||
kprintf("this example is intended for MODE=asan or MODE=dbg\n");
|
||||
printf("this example is intended for MODE=asan or MODE=dbg\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
kprintf("----------------\n");
|
||||
kprintf(" THIS IS A TEST \n");
|
||||
kprintf("SIMULATING CRASH\n");
|
||||
kprintf("----------------\n");
|
||||
|
||||
char *buffer;
|
||||
ShowCrashReports(); /* not needed but yoinks appropriate symbols */
|
||||
buffer = malloc(13);
|
||||
|
||||
+7
-7
@@ -20,22 +20,22 @@ int main(int argc, char *argv[]) {
|
||||
volatile unsigned long x;
|
||||
struct timespec now, start, next, interval;
|
||||
printf("hammering the cpu...\n");
|
||||
next = start = timespec_mono();
|
||||
interval = timespec_frommillis(500);
|
||||
next = timespec_add(next, interval);
|
||||
next = start = _timespec_mono();
|
||||
interval = _timespec_frommillis(500);
|
||||
next = _timespec_add(next, interval);
|
||||
for (;;) {
|
||||
for (i = 0;; ++i) {
|
||||
x *= 7;
|
||||
if (!(i % 256)) {
|
||||
now = timespec_mono();
|
||||
if (timespec_cmp(now, next) >= 0) {
|
||||
now = _timespec_mono();
|
||||
if (_timespec_gte(now, next)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
next = timespec_add(next, interval);
|
||||
next = _timespec_add(next, interval);
|
||||
printf("consumed %10g seconds monotonic time and %10g seconds cpu time\n",
|
||||
timespec_tonanos(timespec_sub(now, start)) / 1000000000.,
|
||||
_timespec_tonanos(_timespec_sub(now, start)) / 1000000000.,
|
||||
(double)clock() / CLOCKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ void show(int clock) {
|
||||
}
|
||||
shown[n++] = clock;
|
||||
if (clock_getres(clock, &ts) != -1) {
|
||||
kprintf("%s %'ld ns\n", DescribeClockName(clock), timespec_tonanos(ts));
|
||||
kprintf("%s %'ld ns\n", DescribeClockName(clock), _timespec_tonanos(ts));
|
||||
} else {
|
||||
kprintf("%s %s\n", DescribeClockName(clock), _strerrno(errno));
|
||||
}
|
||||
@@ -38,12 +38,10 @@ int main(int argc, char *argv[]) {
|
||||
show(CLOCK_REALTIME);
|
||||
show(CLOCK_REALTIME_FAST);
|
||||
show(CLOCK_REALTIME_PRECISE);
|
||||
show(CLOCK_REALTIME_COARSE);
|
||||
show(CLOCK_MONOTONIC);
|
||||
show(CLOCK_MONOTONIC_RAW);
|
||||
show(CLOCK_MONOTONIC_FAST);
|
||||
show(CLOCK_MONOTONIC_PRECISE);
|
||||
show(CLOCK_MONOTONIC_COARSE);
|
||||
show(CLOCK_PROCESS_CPUTIME_ID);
|
||||
show(CLOCK_THREAD_CPUTIME_ID);
|
||||
show(CLOCK_PROF);
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
|
||||
@@ -25,12 +24,6 @@
|
||||
*/
|
||||
|
||||
noubsan int main(int argc, char *argv[]) {
|
||||
|
||||
kprintf("----------------\n");
|
||||
kprintf(" THIS IS A TEST \n");
|
||||
kprintf("SIMULATING CRASH\n");
|
||||
kprintf("----------------\n");
|
||||
|
||||
volatile int64_t x;
|
||||
ShowCrashReports();
|
||||
return 1 / (x = 0);
|
||||
|
||||
@@ -52,10 +52,12 @@
|
||||
#include "third_party/mbedtls/pk.h"
|
||||
#include "third_party/mbedtls/ssl.h"
|
||||
#include "third_party/mbedtls/ssl_ticket.h"
|
||||
#include "tool/curl/cmd.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Downloads HTTP URL to stdout.
|
||||
*
|
||||
* make -j8 o//examples/curl.com
|
||||
* o//examples/curl.com http://justine.lol/ape.html
|
||||
*/
|
||||
|
||||
#define HasHeader(H) (!!msg.headers[H].a)
|
||||
@@ -115,11 +117,11 @@ static int TlsRecv(void *c, unsigned char *p, size_t n, uint32_t o) {
|
||||
}
|
||||
|
||||
static wontreturn void PrintUsage(FILE *f, int rc) {
|
||||
fprintf(f, "usage: %s [-iksvV] URL\n", program_invocation_name);
|
||||
fprintf(f, "usage: %s [-ksvV] URL\n", program_invocation_name);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
int _curl(int argc, char *argv[]) {
|
||||
int main(int argc, char *argv[]) {
|
||||
if (!NoDebug()) ShowCrashReports();
|
||||
|
||||
/*
|
||||
@@ -130,13 +132,11 @@ int _curl(int argc, char *argv[]) {
|
||||
size_t n;
|
||||
char **p;
|
||||
} headers = {0};
|
||||
int method = 0;
|
||||
int method = kHttpGet;
|
||||
bool authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
bool includeheaders = false;
|
||||
const char *postdata = NULL;
|
||||
const char *agent = "hurl/1.o (https://github.com/jart/cosmopolitan)";
|
||||
__log_level = kLogWarn;
|
||||
while ((opt = getopt(argc, argv, "qiksvVIX:H:A:d:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "qksvVIX:H:A:")) != -1) {
|
||||
switch (opt) {
|
||||
case 's':
|
||||
case 'q':
|
||||
@@ -144,9 +144,6 @@ int _curl(int argc, char *argv[]) {
|
||||
case 'v':
|
||||
++__log_level;
|
||||
break;
|
||||
case 'i':
|
||||
includeheaders = true;
|
||||
break;
|
||||
case 'I':
|
||||
method = kHttpHead;
|
||||
break;
|
||||
@@ -157,9 +154,6 @@ int _curl(int argc, char *argv[]) {
|
||||
headers.p = realloc(headers.p, ++headers.n * sizeof(*headers.p));
|
||||
headers.p[headers.n - 1] = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
postdata = optarg;
|
||||
break;
|
||||
case 'X':
|
||||
CHECK((method = GetHttpMethod(optarg, strlen(optarg))));
|
||||
break;
|
||||
@@ -230,29 +224,17 @@ int _curl(int argc, char *argv[]) {
|
||||
/*
|
||||
* Create HTTP message.
|
||||
*/
|
||||
if (!method) method = postdata ? kHttpPost : kHttpGet;
|
||||
|
||||
char *request = 0;
|
||||
appendf(&request,
|
||||
"%s %s HTTP/1.1\r\n"
|
||||
"Host: %s:%s\r\n"
|
||||
"Connection: close\r\n"
|
||||
"User-Agent: %s\r\n",
|
||||
kHttpMethod[method], _gc(EncodeUrl(&url, 0)), agent);
|
||||
|
||||
bool senthost = false, sentcontenttype = false, sentcontentlength = false;
|
||||
kHttpMethod[method], _gc(EncodeUrl(&url, 0)), host, port, agent);
|
||||
for (int i = 0; i < headers.n; ++i) {
|
||||
appendf(&request, "%s\r\n", headers.p[i]);
|
||||
if (!strncasecmp("Host:", headers.p[i], 5)) senthost = true;
|
||||
else if (!strncasecmp("Content-Type:", headers.p[i], 13)) sentcontenttype = true;
|
||||
else if (!strncasecmp("Content-Length:", headers.p[i], 15)) sentcontentlength = true;
|
||||
}
|
||||
if (!senthost) appendf(&request, "Host: %s:%s\r\n", host, port);
|
||||
if (postdata) {
|
||||
if (!sentcontenttype) appends(&request, "Content-Type: application/x-www-form-urlencoded\r\n");
|
||||
if (!sentcontentlength) appendf(&request, "Content-Length: %d\r\n", strlen(postdata));
|
||||
}
|
||||
appendf(&request, "\r\n");
|
||||
if (postdata) appends(&request, postdata);
|
||||
|
||||
/*
|
||||
* Setup crypto.
|
||||
@@ -280,7 +262,7 @@ int _curl(int argc, char *argv[]) {
|
||||
* Perform DNS lookup.
|
||||
*/
|
||||
struct addrinfo *addr;
|
||||
struct addrinfo hints = {.ai_family = AF_UNSPEC,
|
||||
struct addrinfo hints = {.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
.ai_protocol = IPPROTO_TCP,
|
||||
.ai_flags = AI_NUMERICSERV};
|
||||
@@ -362,10 +344,10 @@ int _curl(int argc, char *argv[]) {
|
||||
i -= hdrlen;
|
||||
break;
|
||||
}
|
||||
if (method == kHttpHead || includeheaders) {
|
||||
if (method == kHttpHead) {
|
||||
Write(p, hdrlen);
|
||||
}
|
||||
if (method == kHttpHead || msg.status == 204 || msg.status == 304) {
|
||||
goto Finished;
|
||||
} else if (msg.status == 204 || msg.status == 304) {
|
||||
goto Finished;
|
||||
}
|
||||
if (HasHeader(kHttpTransferEncoding) &&
|
||||
+1
-24
@@ -49,12 +49,12 @@ EXAMPLES_DIRECTDEPS = \
|
||||
LIBC_LOG \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_ADVAPI32 \
|
||||
LIBC_NT_IPHLPAPI \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_NT_NTDLL \
|
||||
LIBC_NT_USER32 \
|
||||
LIBC_NT_WS2_32 \
|
||||
LIBC_NT_ADVAPI32 \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_SOCK \
|
||||
LIBC_STDIO \
|
||||
@@ -71,7 +71,6 @@ EXAMPLES_DIRECTDEPS = \
|
||||
LIBC_ZIPOS \
|
||||
NET_HTTP \
|
||||
NET_HTTPS \
|
||||
THIRD_PARTY_AWK \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_DOUBLECONVERSION \
|
||||
@@ -80,15 +79,12 @@ EXAMPLES_DIRECTDEPS = \
|
||||
THIRD_PARTY_LIBCXX \
|
||||
THIRD_PARTY_LINENOISE \
|
||||
THIRD_PARTY_LUA \
|
||||
THIRD_PARTY_HIREDIS \
|
||||
THIRD_PARTY_MBEDTLS \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_NSYNC \
|
||||
THIRD_PARTY_NSYNC_MEM \
|
||||
THIRD_PARTY_QUICKJS \
|
||||
THIRD_PARTY_SED \
|
||||
THIRD_PARTY_STB \
|
||||
THIRD_PARTY_TR \
|
||||
THIRD_PARTY_XED \
|
||||
THIRD_PARTY_ZLIB \
|
||||
TOOL_BUILD_LIB \
|
||||
@@ -147,25 +143,6 @@ o/$(MODE)/examples/nesemu1.com.dbg: \
|
||||
$(EXAMPLES_BOOTLOADER)
|
||||
@$(APELINK)
|
||||
|
||||
# # force symtab.com to be a zip file, by pulling a zip asset into linkage
|
||||
# # we wouldn't need to do this if we depended on functions like localtime
|
||||
# o/$(MODE)/examples/symtab.com.dbg: \
|
||||
# $(EXAMPLES_DEPS) \
|
||||
# o/$(MODE)/examples/symtab.o \
|
||||
# o/$(MODE)/examples/symtab.c.zip.o \
|
||||
# o/$(MODE)/examples/examples.pkg \
|
||||
# $(EXAMPLES_BOOTLOADER)
|
||||
# @$(APELINK)
|
||||
|
||||
# modify .com so it can read the symbol table without needing the .com.dbg file
|
||||
o/$(MODE)/examples/symtab.com: \
|
||||
o/$(MODE)/examples/symtab.com.dbg \
|
||||
o/$(MODE)/third_party/zip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com
|
||||
@$(MAKE_OBJCOPY)
|
||||
@$(MAKE_SYMTAB_CREATE)
|
||||
@$(MAKE_SYMTAB_ZIP)
|
||||
|
||||
o/$(MODE)/examples/picol.o: private \
|
||||
OVERRIDE_CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "ape/sections.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/errno.h"
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
#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/runtime/runtime.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/hiredis/hiredis.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Demo of using hiredis to connect to a Redis server
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 3 || argc > 5) {
|
||||
fprintf(stderr, "Usage: %s HOST PORT [KEY] [VALUE]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bool setValue = (argc == 5), getValue = (argc == 4);
|
||||
|
||||
redisContext *c = redisConnect(argv[1], atoi(argv[2]));
|
||||
if (c == NULL || c->err) {
|
||||
if (c) {
|
||||
fprintf(stderr, "Connection error: %s\n", c->errstr);
|
||||
redisFree(c);
|
||||
} else {
|
||||
fputs("Failed to allocate redis context\n", stderr);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
redisReply *reply;
|
||||
if (!setValue && !getValue) {
|
||||
reply = redisCommand(c, "PING");
|
||||
printf("PING: %s\n", reply->str);
|
||||
} else if (setValue) {
|
||||
reply = redisCommand(c, "SET %s %s", argv[3], argv[4]);
|
||||
printf("SET: %s\n", reply->str);
|
||||
} else {
|
||||
reply = redisCommand(c, "GET %s", argv[3]);
|
||||
printf("GET: %s\n", reply->str);
|
||||
}
|
||||
|
||||
freeReplyObject(reply);
|
||||
redisFree(c);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#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/assert.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
|
||||
/**
|
||||
* @fileoverview shows how accurate clock_nanosleep() is
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
long i, ns;
|
||||
struct timespec x, y, w;
|
||||
timespec_sleep(timespec_fromnanos(0)); // warmup
|
||||
|
||||
printf("\nrelative sleep\n");
|
||||
for (i = 0; i < 28; ++i) {
|
||||
ns = 1l << i;
|
||||
x = timespec_real();
|
||||
timespec_sleep(timespec_fromnanos(ns));
|
||||
y = timespec_real();
|
||||
printf("%,11ld ns sleep took %,ld ns\n", ns,
|
||||
timespec_tonanos(timespec_sub(y, x)));
|
||||
}
|
||||
|
||||
printf("\nabsolute sleep\n");
|
||||
for (i = 0; i < 28; ++i) {
|
||||
ns = 1l << i;
|
||||
x = timespec_real();
|
||||
timespec_sleep_until(timespec_add(x, timespec_fromnanos(ns)));
|
||||
y = timespec_real();
|
||||
printf("%,11ld ns sleep took %,ld ns\n", ns,
|
||||
timespec_tonanos(timespec_sub(y, x)));
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -47,7 +47,7 @@
|
||||
#include "third_party/libcxx/vector"
|
||||
#include "tool/viz/lib/knobs.h"
|
||||
|
||||
STATIC_YOINK("zipos");
|
||||
STATIC_YOINK("zip_uri_support");
|
||||
|
||||
#define USAGE \
|
||||
" [ROM] [FMV]\n\
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "ape/sections.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
#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/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/struct/sockaddr.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/ipproto.h"
|
||||
#include "libc/sysv/consts/so.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
#include "net/http/ip.h"
|
||||
|
||||
/**
|
||||
* @fileoverview fast local network port scanner, e.g.
|
||||
*
|
||||
* make -j8 o//examples/portscan.com
|
||||
* o//examples/portscan.com 10.10.10.0/24 22
|
||||
*/
|
||||
|
||||
const char *FormatIp(char buf[16], uint32_t ip) {
|
||||
snprintf(buf, 16, "%hhu.%hhu.%hhu.%hhu", ip >> 24, ip >> 16, ip >> 8, ip);
|
||||
return buf;
|
||||
}
|
||||
|
||||
#define FormatIp(x) FormatIp(alloca(16), x)
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int port;
|
||||
struct Cidr in;
|
||||
uint32_t netmask;
|
||||
const char *status;
|
||||
struct timeval timeout;
|
||||
uint32_t network_address;
|
||||
uint32_t last_host_address;
|
||||
uint32_t first_host_address;
|
||||
|
||||
if (argc != 3) {
|
||||
PrintUsage:
|
||||
fprintf(stderr,
|
||||
"usage: %s IP/CIDR PORT\n"
|
||||
"example: %s 192.168.0.0/24 22\n",
|
||||
argv[0], argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
in = ParseCidr(argv[1], -1);
|
||||
if (in.addr == -1) {
|
||||
fprintf(stderr, "error: bad ip/cidr\n");
|
||||
goto PrintUsage;
|
||||
}
|
||||
|
||||
port = atoi(argv[2]);
|
||||
if (!(1 <= port && port <= 65535)) {
|
||||
fprintf(stderr, "error: bad port\n");
|
||||
goto PrintUsage;
|
||||
}
|
||||
|
||||
if (in.cidr > 30) {
|
||||
fprintf(stderr, "error: maximum supported cidr is 30\n");
|
||||
goto PrintUsage;
|
||||
}
|
||||
|
||||
if (in.cidr < 22) {
|
||||
fprintf(stderr, "error: minimum cidr support right now is 22\n");
|
||||
goto PrintUsage;
|
||||
}
|
||||
|
||||
netmask = -1u << (32 - in.cidr);
|
||||
network_address = in.addr & netmask;
|
||||
first_host_address = network_address + 1;
|
||||
last_host_address = (network_address | ~netmask) - 1;
|
||||
|
||||
assert(last_host_address > first_host_address);
|
||||
assert(last_host_address - first_host_address < 1024);
|
||||
|
||||
fprintf(stderr, "scanning %s through %s\n", FormatIp(first_host_address),
|
||||
FormatIp(last_host_address));
|
||||
|
||||
timeout = timeval_frommillis(100);
|
||||
for (int64_t ip = first_host_address; ip <= last_host_address; ++ip) {
|
||||
if (!fork()) {
|
||||
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
setsockopt(3, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
|
||||
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
|
||||
if (!connect(3,
|
||||
(struct sockaddr *)&(struct sockaddr_in){
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = htonl(ip),
|
||||
.sin_port = htons(port),
|
||||
},
|
||||
sizeof(struct sockaddr_in))) {
|
||||
status = "open";
|
||||
} else if (errno == ECONNREFUSED) {
|
||||
status = "closed";
|
||||
} else if (errno != EINPROGRESS) {
|
||||
status = _strerrno(errno);
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
if (status) {
|
||||
printf("%-15s %s\n", FormatIp(ip), status);
|
||||
}
|
||||
_Exit(0);
|
||||
}
|
||||
}
|
||||
for (;;) {
|
||||
if (wait(0) == -1 && errno == ECHILD) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#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/calls/calls.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/reboot.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char line[8] = {0};
|
||||
if (argc > 1 && !strcmp(argv[1], "-y")) {
|
||||
line[0] = 'y';
|
||||
} else {
|
||||
printf("reboot your computer? yes or no [no] ");
|
||||
fflush(stdout);
|
||||
fgets(line, sizeof(line), stdin);
|
||||
}
|
||||
if (line[0] == 'y' || line[0] == 'Y') {
|
||||
if (reboot(RB_AUTOBOOT)) {
|
||||
printf("system is rebooting...\n");
|
||||
exit(0);
|
||||
} else {
|
||||
perror("reboot");
|
||||
exit(1);
|
||||
}
|
||||
} else if (line[0] == 'n' || line[0] == 'N') {
|
||||
exit(0);
|
||||
} else {
|
||||
printf("error: unrecognized response\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#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/calls/calls.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/reboot.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char line[8] = {0};
|
||||
if (argc > 1 && !strcmp(argv[1], "-y")) {
|
||||
line[0] = 'y';
|
||||
} else {
|
||||
printf("shutdown your computer? yes or no [no] ");
|
||||
fflush(stdout);
|
||||
fgets(line, sizeof(line), stdin);
|
||||
}
|
||||
if (line[0] == 'y' || line[0] == 'Y') {
|
||||
if (reboot(RB_POWER_OFF)) {
|
||||
printf("system is shutting down...\n");
|
||||
exit(0);
|
||||
} else {
|
||||
perror("reboot");
|
||||
exit(1);
|
||||
}
|
||||
} else if (line[0] == 'n' || line[0] == 'N') {
|
||||
exit(0);
|
||||
} else {
|
||||
printf("error: unrecognized response\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -1,42 +0,0 @@
|
||||
#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/intrin/kprintf.h"
|
||||
#include "libc/log/log.h"
|
||||
|
||||
/**
|
||||
* @fileoverview example of how to embed symbol table in .com file
|
||||
*
|
||||
* # build our binary
|
||||
* make -j16 o//examples/symtab.com
|
||||
*
|
||||
* # move binary somewhere else
|
||||
* # so it can't find the .com.dbg binary
|
||||
* cp o//examples/symtab.com /tmp
|
||||
*
|
||||
* # run program
|
||||
* # notice that it has a symbolic backtrace
|
||||
* /tmp/symtab.com
|
||||
*
|
||||
* @see examples/examples.mk
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
// this links all the debugging and zip functionality
|
||||
ShowCrashReports();
|
||||
|
||||
kprintf("----------------\n");
|
||||
kprintf(" THIS IS A TEST \n");
|
||||
kprintf("SIMULATING CRASH\n");
|
||||
kprintf("----------------\n");
|
||||
|
||||
volatile int64_t x;
|
||||
return 1 / (x = 0);
|
||||
}
|
||||
+6
-13
@@ -7,20 +7,13 @@
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Cosmopolitan Command Interpreter Demo
|
||||
* Yes this works on Windows.
|
||||
*/
|
||||
|
||||
STATIC_YOINK("_tr");
|
||||
STATIC_YOINK("_sed");
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
system("x=world\n"
|
||||
"echo hello $x |\n"
|
||||
" tr a-z A-Z |\n"
|
||||
" sed 's/\\(.\\)/\\1 /g'");
|
||||
if (IsWindows()) {
|
||||
system("notepad");
|
||||
} else {
|
||||
system("ls | tr a-z A-Z");
|
||||
}
|
||||
}
|
||||
@@ -24,16 +24,10 @@
|
||||
|
||||
STATIC_YOINK("vga_console");
|
||||
STATIC_YOINK("_idt");
|
||||
STATIC_YOINK("EfiMain");
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
volatile int x = 1;
|
||||
volatile int y = 2;
|
||||
printf("argc = %d\n", argc);
|
||||
for (i = 0; i < argc; ++i) {
|
||||
printf("argv[%d] = \"%s\"\n", i, argv[i]);
|
||||
}
|
||||
printf("\e[92;44mHello World!\e[0m %d\n", 1 / (x + y - 3));
|
||||
for (;;);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_AR_H_
|
||||
#define COSMOPOLITAN_LIBC_AR_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define ARMAG "!<arch>\n"
|
||||
#define SARMAG 8
|
||||
#define ARFMAG "`\n"
|
||||
|
||||
struct ar_hdr {
|
||||
char ar_name[16];
|
||||
char ar_date[12];
|
||||
char ar_uid[6], ar_gid[6];
|
||||
char ar_mode[8];
|
||||
char ar_size[10];
|
||||
char ar_fmag[2];
|
||||
};
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_AR_H_ */
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern bool __assert_disable;
|
||||
void __assert_fail(const char *, const char *, int) _Hide relegated;
|
||||
void __assert_fail(const char *, const char *, int) hidden relegated;
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define assert(x) ((void)0)
|
||||
@@ -17,7 +17,7 @@ void __assert_fail(const char *, const char *, int) _Hide relegated;
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if !defined(TINY) && !defined(MODE_DBG)
|
||||
#ifndef TINY
|
||||
/**
|
||||
* Specifies expression can't possibly be false.
|
||||
*
|
||||
|
||||
+6
-4
@@ -16,7 +16,6 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/sections.internal.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
@@ -108,6 +107,7 @@ static bool __sig_deliver(bool restartable, int sig, int si_code,
|
||||
STRACE("delivering %G", sig);
|
||||
|
||||
// enter the signal
|
||||
__sig_lock();
|
||||
rva = __sighandrvas[sig];
|
||||
flags = __sighandflags[sig];
|
||||
if ((~flags & SA_NODEFER) || (flags & SA_RESETHAND)) {
|
||||
@@ -118,6 +118,7 @@ static bool __sig_deliver(bool restartable, int sig, int si_code,
|
||||
// signal handler. in that case you must use SA_NODEFER.
|
||||
__sighandrvas[sig] = (int32_t)(intptr_t)SIG_DFL;
|
||||
}
|
||||
__sig_unlock();
|
||||
|
||||
// setup the somewhat expensive information args
|
||||
// only if they're requested by the user in sigaction()
|
||||
@@ -139,9 +140,11 @@ static bool __sig_deliver(bool restartable, int sig, int si_code,
|
||||
// since sigaction() is @asyncsignalsafe we only restore it if the
|
||||
// user didn't change it during the signal handler. we also don't
|
||||
// need to do anything if this was a oneshot signal or nodefer.
|
||||
__sig_lock();
|
||||
if (__sighandrvas[sig] == (int32_t)(intptr_t)SIG_DFL) {
|
||||
__sighandrvas[sig] = rva;
|
||||
}
|
||||
__sig_unlock();
|
||||
}
|
||||
|
||||
if (!restartable) {
|
||||
@@ -204,7 +207,6 @@ textwindows int __sig_raise(int sig, int si_code) {
|
||||
if (1 <= sig && sig <= 64) {
|
||||
if (!__sig_is_masked(sig)) {
|
||||
++__sig_count;
|
||||
// TODO(jart): ucontext_t support
|
||||
__sig_handle(false, sig, si_code, 0);
|
||||
return 0;
|
||||
} else {
|
||||
@@ -225,12 +227,12 @@ textwindows int __sig_add(int tid, int sig, int si_code) {
|
||||
int rc;
|
||||
struct Signal *mem;
|
||||
if (1 <= sig && sig <= 64) {
|
||||
__sig_lock();
|
||||
if (__sighandrvas[sig] == (unsigned)(intptr_t)SIG_IGN) {
|
||||
STRACE("ignoring %G", sig);
|
||||
rc = 0;
|
||||
} else {
|
||||
STRACE("enqueuing %G", sig);
|
||||
__sig_lock();
|
||||
++__sig_count;
|
||||
if ((mem = __sig_alloc())) {
|
||||
mem->tid = tid;
|
||||
@@ -242,8 +244,8 @@ textwindows int __sig_add(int tid, int sig, int si_code) {
|
||||
} else {
|
||||
rc = enomem();
|
||||
}
|
||||
__sig_unlock();
|
||||
}
|
||||
__sig_unlock();
|
||||
} else {
|
||||
rc = einval();
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/thread/tls.h"
|
||||
@@ -47,10 +45,7 @@ textwindows int __sig_mask(int how, const sigset_t *neu, sigset_t *old) {
|
||||
} else {
|
||||
x = y;
|
||||
}
|
||||
x &= ~(0
|
||||
#define M(x) | GetSigBit(x)
|
||||
#include "libc/intrin/sigisprecious.inc"
|
||||
);
|
||||
x &= ~(GetSigBit(SIGKILL) | GetSigBit(SIGSTOP) | GetSigBit(SIGABRT));
|
||||
*mask = x;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
/**
|
||||
* Adds two nanosecond timestamps.
|
||||
*/
|
||||
struct timespec timespec_add(struct timespec x, struct timespec y) {
|
||||
struct timespec _timespec_add(struct timespec x, struct timespec y) {
|
||||
x.tv_sec += y.tv_sec;
|
||||
x.tv_nsec += y.tv_nsec;
|
||||
if (x.tv_nsec >= 1000000000) {
|
||||
@@ -20,10 +20,8 @@
|
||||
|
||||
/**
|
||||
* Compares nanosecond timestamps.
|
||||
*
|
||||
* @return 0 if equal, -1 if `a < b`, or +1 if `a > b`
|
||||
*/
|
||||
int timespec_cmp(struct timespec a, struct timespec b) {
|
||||
int _timespec_cmp(struct timespec a, struct timespec b) {
|
||||
int cmp;
|
||||
if (!(cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec))) {
|
||||
cmp = (a.tv_nsec > b.tv_nsec) - (a.tv_nsec < b.tv_nsec);
|
||||
@@ -16,11 +16,11 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
|
||||
sigset_t _sigblockall(void) {
|
||||
sigset_t ss;
|
||||
memset(&ss, -1, sizeof(ss));
|
||||
return _sigsetmask(ss);
|
||||
/**
|
||||
* Checks if 𝑥 = 𝑦.
|
||||
*/
|
||||
bool _timespec_eq(struct timespec x, struct timespec y) {
|
||||
return x.tv_sec == y.tv_sec && x.tv_nsec == y.tv_nsec;
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
/**
|
||||
* Converts timespec interval from microseconds.
|
||||
*/
|
||||
struct timespec timespec_frommicros(int64_t x) {
|
||||
struct timespec _timespec_frommicros(int64_t x) {
|
||||
struct timespec ts;
|
||||
ts.tv_sec = x / 1000000;
|
||||
ts.tv_nsec = x % 1000000 * 1000;
|
||||
@@ -21,7 +21,7 @@
|
||||
/**
|
||||
* Converts timespec interval from milliseconds.
|
||||
*/
|
||||
struct timespec timespec_frommillis(int64_t x) {
|
||||
struct timespec _timespec_frommillis(int64_t x) {
|
||||
struct timespec ts;
|
||||
ts.tv_sec = x / 1000;
|
||||
ts.tv_nsec = x % 1000 * 1000000;
|
||||
@@ -21,7 +21,7 @@
|
||||
/**
|
||||
* Converts timespec interval from nanoseconds.
|
||||
*/
|
||||
struct timespec timespec_fromnanos(int64_t x) {
|
||||
struct timespec _timespec_fromnanos(int64_t x) {
|
||||
struct timespec ts;
|
||||
ts.tv_sec = x / 1000000000;
|
||||
ts.tv_nsec = x % 1000000000;
|
||||
@@ -26,7 +26,7 @@
|
||||
* @param ts receives `CLOCK_REALTIME` timestamp
|
||||
* @param base must be `TIME_UTC`
|
||||
* @return `base` on success, or `0` on failure
|
||||
* @see timespec_real()
|
||||
* @see _timespec_real()
|
||||
*/
|
||||
int timespec_get(struct timespec *ts, int base) {
|
||||
if (base == TIME_UTC && !clock_gettime(CLOCK_REALTIME, ts)) {
|
||||
File renamed without changes.
@@ -0,0 +1,34 @@
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 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 "libc/calls/struct/timespec.h"
|
||||
|
||||
/**
|
||||
* Returns true if timespec `x` is greater than `y`.
|
||||
*/
|
||||
bool _timespec_gt(struct timespec x, struct timespec y) {
|
||||
if (x.tv_sec > y.tv_sec) {
|
||||
return true;
|
||||
}
|
||||
if (x.tv_sec == y.tv_sec) {
|
||||
if (x.tv_nsec > y.tv_nsec) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 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 "libc/calls/struct/timespec.h"
|
||||
|
||||
/**
|
||||
* Checks if 𝑥 ≥ 𝑦.
|
||||
*/
|
||||
bool _timespec_gte(struct timespec x, struct timespec y) {
|
||||
if (x.tv_sec > y.tv_sec) return true;
|
||||
if (x.tv_sec < y.tv_sec) return false;
|
||||
return x.tv_nsec >= y.tv_nsec;
|
||||
}
|
||||
@@ -25,10 +25,10 @@
|
||||
*
|
||||
* This function uses a `CLOCK_MONOTONIC` clock and never fails.
|
||||
*
|
||||
* @see timespec_real()
|
||||
* @see _timespec_real()
|
||||
*/
|
||||
struct timespec timespec_mono(void) {
|
||||
struct timespec _timespec_mono(void) {
|
||||
struct timespec ts;
|
||||
_npassert(!clock_gettime(CLOCK_MONOTONIC, &ts));
|
||||
_npassert(!clock_gettime(CLOCK_MONOTONIC_FAST, &ts));
|
||||
return ts;
|
||||
}
|
||||
@@ -27,10 +27,10 @@
|
||||
* clock_gettime() or timespec_real() this interface avoids the use of
|
||||
* pointers which lets time handling code become more elegant.
|
||||
*
|
||||
* @see timespec_mono()
|
||||
* @see _timespec_mono()
|
||||
*/
|
||||
struct timespec timespec_real(void) {
|
||||
struct timespec _timespec_real(void) {
|
||||
struct timespec ts;
|
||||
_npassert(!clock_gettime(CLOCK_REALTIME, &ts));
|
||||
_npassert(!clock_gettime(CLOCK_REALTIME_FAST, &ts));
|
||||
return ts;
|
||||
}
|
||||
@@ -17,10 +17,8 @@
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
|
||||
/**
|
||||
@@ -28,14 +26,13 @@
|
||||
*
|
||||
* @return unslept time which may be non-zero if the call was interrupted
|
||||
*/
|
||||
struct timespec timespec_sleep(struct timespec delay) {
|
||||
errno_t rc;
|
||||
struct timespec _timespec_sleep(struct timespec delay) {
|
||||
int rc;
|
||||
struct timespec remain;
|
||||
BLOCK_CANCELLATIONS;
|
||||
bzero(&remain, sizeof(remain));
|
||||
if ((rc = clock_nanosleep(CLOCK_REALTIME, 0, &delay, &remain))) {
|
||||
if (!(rc = clock_nanosleep(CLOCK_REALTIME, 0, &delay, &remain))) {
|
||||
return (struct timespec){0};
|
||||
} else {
|
||||
_npassert(rc == EINTR);
|
||||
return remain;
|
||||
}
|
||||
ALLOW_CANCELLATIONS;
|
||||
return remain;
|
||||
}
|
||||
@@ -26,13 +26,10 @@
|
||||
* Sleeps until the specified time.
|
||||
*
|
||||
* @return 0 on success, or EINTR if interrupted
|
||||
* @raise ECANCELED if thread was cancelled in masked mode
|
||||
* @raise EINTR if signal was delivered
|
||||
* @cancellationpoint
|
||||
*/
|
||||
errno_t timespec_sleep_until(struct timespec abs_deadline) {
|
||||
errno_t rc;
|
||||
int _timespec_sleep_until(struct timespec abs_deadline) {
|
||||
int rc;
|
||||
rc = clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &abs_deadline, 0);
|
||||
_npassert(!rc || rc == EINTR || rc == ECANCELED);
|
||||
_npassert(!rc || rc == EINTR);
|
||||
return rc;
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
/**
|
||||
* Subtracts two nanosecond timestamps.
|
||||
*/
|
||||
struct timespec timespec_sub(struct timespec a, struct timespec b) {
|
||||
struct timespec _timespec_sub(struct timespec a, struct timespec b) {
|
||||
a.tv_sec -= b.tv_sec;
|
||||
if (a.tv_nsec < b.tv_nsec) {
|
||||
a.tv_nsec += 1000000000;
|
||||
@@ -31,9 +31,9 @@
|
||||
* `INT64_MIN` may be returned. The `errno` variable isn't changed.
|
||||
*
|
||||
* @return 64-bit scalar holding microseconds since epoch
|
||||
* @see timespec_totimeval()
|
||||
* @see _timespec_totimeval()
|
||||
*/
|
||||
int64_t timespec_tomicros(struct timespec ts) {
|
||||
int64_t _timespec_tomicros(struct timespec ts) {
|
||||
int64_t us;
|
||||
// reduce precision from nanos to micros
|
||||
if (ts.tv_nsec <= 999999000) {
|
||||
@@ -32,7 +32,7 @@
|
||||
*
|
||||
* @return 64-bit scalar milliseconds since epoch
|
||||
*/
|
||||
int64_t timespec_tomillis(struct timespec ts) {
|
||||
int64_t _timespec_tomillis(struct timespec ts) {
|
||||
int64_t ms;
|
||||
// reduce precision from nanos to millis
|
||||
if (ts.tv_nsec <= 999000000) {
|
||||
@@ -22,13 +22,12 @@
|
||||
/**
|
||||
* Converts timespec to scalar.
|
||||
*
|
||||
* This returns the absolute number of nanoseconds in a timespec. If
|
||||
* overflow happens, then `INT64_MAX` or `INT64_MIN` is returned. The
|
||||
* `errno` variable isn't changed.
|
||||
* This function will detect overflow in which case `INT64_MAX` or
|
||||
* `INT64_MIN` may be returned. The `errno` variable isn't changed.
|
||||
*
|
||||
* @return 64-bit integer holding nanoseconds since epoch
|
||||
*/
|
||||
int64_t timespec_tonanos(struct timespec x) {
|
||||
int64_t _timespec_tonanos(struct timespec x) {
|
||||
int64_t ns;
|
||||
if (!__builtin_mul_overflow(x.tv_sec, 1000000000ul, &ns) &&
|
||||
!__builtin_add_overflow(ns, x.tv_nsec, &ns)) {
|
||||
@@ -27,9 +27,9 @@
|
||||
* timestamp has a special meaning.
|
||||
*
|
||||
* @return microseconds since epoch
|
||||
* @see timespec_tomicros()
|
||||
* @see _timespec_tomicros()
|
||||
*/
|
||||
struct timeval timespec_totimeval(struct timespec ts) {
|
||||
struct timeval _timespec_totimeval(struct timespec ts) {
|
||||
if (ts.tv_nsec < 1000000000 - 999) {
|
||||
return (struct timeval){ts.tv_sec, (ts.tv_nsec + 999) / 1000};
|
||||
} else {
|
||||
@@ -21,7 +21,7 @@
|
||||
/**
|
||||
* Adds two microsecond timestamps.
|
||||
*/
|
||||
struct timeval timeval_add(struct timeval x, struct timeval y) {
|
||||
struct timeval _timeval_add(struct timeval x, struct timeval y) {
|
||||
x.tv_sec += y.tv_sec;
|
||||
x.tv_usec += y.tv_usec;
|
||||
if (x.tv_usec >= 1000000) {
|
||||
@@ -19,11 +19,9 @@
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
|
||||
/**
|
||||
* Compares microsecond timestamps.
|
||||
*
|
||||
* @return 0 if equal, -1 if `a < b`, or +1 if `a > b`
|
||||
* Compares microseconds timestamps.
|
||||
*/
|
||||
int timeval_cmp(struct timeval a, struct timeval b) {
|
||||
int _timeval_cmp(struct timeval a, struct timeval b) {
|
||||
int cmp;
|
||||
if (!(cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec))) {
|
||||
cmp = (a.tv_usec > b.tv_usec) - (a.tv_usec < b.tv_usec);
|
||||
@@ -19,11 +19,8 @@
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
|
||||
/**
|
||||
* Converts timeval interval from microseconds.
|
||||
* Checks if 𝑥 = 𝑦.
|
||||
*/
|
||||
struct timeval timeval_frommicros(int64_t x) {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = x / 1000000;
|
||||
tv.tv_usec = x % 1000000;
|
||||
return tv;
|
||||
bool _timeval_eq(struct timeval x, struct timeval y) {
|
||||
return x.tv_sec == y.tv_sec && x.tv_usec == y.tv_usec;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 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 "libc/calls/struct/timeval.h"
|
||||
|
||||
/**
|
||||
* Returns true if timeval `x` is greater than `y`.
|
||||
*/
|
||||
bool _timeval_gt(struct timeval x, struct timeval y) {
|
||||
if (x.tv_sec > y.tv_sec) {
|
||||
return true;
|
||||
}
|
||||
if (x.tv_sec == y.tv_sec) {
|
||||
if (x.tv_usec > y.tv_usec) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -19,11 +19,10 @@
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
|
||||
/**
|
||||
* Converts timeval interval from milliseconds.
|
||||
* Checks if 𝑥 ≥ 𝑦.
|
||||
*/
|
||||
struct timeval timeval_frommillis(int64_t x) {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = x / 1000;
|
||||
tv.tv_usec = x % 1000 * 1000;
|
||||
return tv;
|
||||
bool _timeval_gte(struct timeval x, struct timeval y) {
|
||||
if (x.tv_sec > y.tv_sec) return true;
|
||||
if (x.tv_sec < y.tv_sec) return false;
|
||||
return x.tv_usec >= y.tv_usec;
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
/**
|
||||
* Subtracts two nanosecond timestamps.
|
||||
*/
|
||||
struct timeval timeval_sub(struct timeval a, struct timeval b) {
|
||||
struct timeval _timeval_sub(struct timeval a, struct timeval b) {
|
||||
a.tv_sec -= b.tv_sec;
|
||||
if (a.tv_usec < b.tv_usec) {
|
||||
a.tv_usec += 1000000;
|
||||
@@ -21,6 +21,6 @@
|
||||
/**
|
||||
* Coerces `tv` from 1e-6 to 1e-9 granularity.
|
||||
*/
|
||||
struct timespec timeval_totimespec(struct timeval tv) {
|
||||
struct timespec _timeval_totimespec(struct timeval tv) {
|
||||
return (struct timespec){tv.tv_sec, tv.tv_usec * 1000};
|
||||
}
|
||||
@@ -22,9 +22,9 @@
|
||||
/**
|
||||
* Accumulates resource statistics in `y` to `x`.
|
||||
*/
|
||||
void rusage_add(struct rusage *x, const struct rusage *y) {
|
||||
x->ru_utime = timeval_add(x->ru_utime, y->ru_utime);
|
||||
x->ru_stime = timeval_add(x->ru_stime, y->ru_stime);
|
||||
void _addrusage(struct rusage *x, const struct rusage *y) {
|
||||
x->ru_utime = _timeval_add(x->ru_utime, y->ru_utime);
|
||||
x->ru_stime = _timeval_add(x->ru_stime, y->ru_stime);
|
||||
x->ru_maxrss = MAX(x->ru_maxrss, y->ru_maxrss);
|
||||
x->ru_ixrss += y->ru_ixrss;
|
||||
x->ru_idrss += y->ru_idrss;
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_BLOCKCANCEL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_BLOCKCANCEL_H_
|
||||
#include "libc/thread/thread.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define BLOCK_CANCELLATIONS \
|
||||
do { \
|
||||
int _CancelState; \
|
||||
_CancelState = _pthread_block_cancellations()
|
||||
|
||||
#define ALLOW_CANCELLATIONS \
|
||||
_pthread_allow_cancellations(_CancelState); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
int _pthread_block_cancellations(void);
|
||||
void _pthread_allow_cancellations(int);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_BLOCKCANCEL_H_ */
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_BLOCKSIGS_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_BLOCKSIGS_H_
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define BLOCK_SIGNALS \
|
||||
do { \
|
||||
sigset_t _SigMask; \
|
||||
_SigMask = _sigblockall()
|
||||
|
||||
#define ALLOW_SIGNALS \
|
||||
_sigsetmask(_SigMask); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_BLOCKSIGS_H_ */
|
||||
+47
-46
@@ -35,10 +35,11 @@
|
||||
#define WIFCONTINUED(s) ((s) == 0xffff)
|
||||
#define WIFEXITED(s) (!WTERMSIG(s))
|
||||
#define WIFSIGNALED(s) ((0xffff & (s)) - 1u < 0xffu)
|
||||
#define WIFSTOPPED(s) ((255 & (s)) == 127)
|
||||
#define WSTOPSIG(s) WEXITSTATUS(s)
|
||||
#define WTERMSIG(s) (127 & (s))
|
||||
#define W_STOPCODE(s) ((s) << 8 | 0177)
|
||||
#define WIFSTOPPED(s) \
|
||||
((short)(((0xffff & (unsigned)(s)) * 0x10001) >> 8) > 0x7f00)
|
||||
#define WSTOPSIG(s) WEXITSTATUS(s)
|
||||
#define WTERMSIG(s) (127 & (s))
|
||||
#define W_STOPCODE(s) ((s) << 8 | 0177)
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
@@ -64,13 +65,13 @@ char *ttyname(int);
|
||||
int access(const char *, int) dontthrow;
|
||||
int arch_prctl();
|
||||
int chdir(const char *);
|
||||
int chmod(const char *, unsigned);
|
||||
int chown(const char *, unsigned, unsigned);
|
||||
int chmod(const char *, uint32_t);
|
||||
int chown(const char *, uint32_t, uint32_t);
|
||||
int chroot(const char *);
|
||||
int close(int);
|
||||
int close_range(unsigned, unsigned, unsigned);
|
||||
int closefrom(int);
|
||||
int creat(const char *, unsigned);
|
||||
int creat(const char *, uint32_t);
|
||||
int dup(int);
|
||||
int dup2(int, int);
|
||||
int dup3(int, int, int);
|
||||
@@ -83,22 +84,25 @@ int execv(const char *, char *const[]);
|
||||
int execve(const char *, char *const[], char *const[]);
|
||||
int execvp(const char *, char *const[]);
|
||||
int execvpe(const char *, char *const[], char *const[]);
|
||||
int fexecve(int, char *const[], char *const[]);
|
||||
int faccessat(int, const char *, int, int);
|
||||
int fadvise(int, uint64_t, uint64_t, int);
|
||||
int fchdir(int);
|
||||
int fchmod(int, unsigned) dontthrow;
|
||||
int fchmodat(int, const char *, unsigned, int);
|
||||
int fchown(int, unsigned, unsigned);
|
||||
int fchownat(int, const char *, unsigned, unsigned, int);
|
||||
int fchmod(int, uint32_t) dontthrow;
|
||||
int fchmodat(int, const char *, uint32_t, int);
|
||||
int fchown(int, uint32_t, uint32_t);
|
||||
int fchownat(int, const char *, uint32_t, uint32_t, int);
|
||||
int fcntl(int, int, ...);
|
||||
int fdatasync(int);
|
||||
int fexecve(int, char *const[], char *const[]);
|
||||
int flock(int, int);
|
||||
int fork(void);
|
||||
int fsync(int);
|
||||
int ftruncate(int, int64_t);
|
||||
int getdomainname(char *, size_t);
|
||||
int getgroups(int, unsigned[]);
|
||||
uint32_t getegid(void) nosideeffect;
|
||||
uint32_t geteuid(void) nosideeffect;
|
||||
uint32_t getgid(void) nosideeffect;
|
||||
int getgroups(int size, uint32_t list[]);
|
||||
int gethostname(char *, size_t);
|
||||
int getloadavg(double *, int);
|
||||
int getpgid(int) libcesque;
|
||||
@@ -106,29 +110,36 @@ int getpgrp(void) nosideeffect;
|
||||
int getpid(void) nosideeffect libcesque;
|
||||
int getppid(void);
|
||||
int getpriority(int, unsigned);
|
||||
int getresgid(unsigned *, unsigned *, unsigned *);
|
||||
int getresuid(unsigned *, unsigned *, unsigned *);
|
||||
int getresgid(uint32_t *, uint32_t *, uint32_t *);
|
||||
int getresuid(uint32_t *, uint32_t *, uint32_t *);
|
||||
int getsid(int) nosideeffect libcesque;
|
||||
int gettid(void) libcesque;
|
||||
uint32_t getuid(void) libcesque;
|
||||
int sys_iopl(int);
|
||||
int ioprio_get(int, int);
|
||||
int ioprio_set(int, int, int);
|
||||
int issetugid(void);
|
||||
int kill(int, int);
|
||||
int killpg(int, int);
|
||||
int lchmod(const char *, unsigned);
|
||||
int lchown(const char *, unsigned, unsigned);
|
||||
int lchmod(const char *, uint32_t);
|
||||
int lchown(const char *, uint32_t, uint32_t);
|
||||
int link(const char *, const char *) dontthrow;
|
||||
int linkat(int, const char *, int, const char *, int);
|
||||
int madvise(void *, uint64_t, int);
|
||||
int makedirs(const char *, unsigned);
|
||||
int memfd_create(const char *, unsigned int);
|
||||
int mincore(void *, size_t, unsigned char *);
|
||||
int mkdir(const char *, unsigned);
|
||||
int mkdirat(int, const char *, unsigned);
|
||||
int mkfifo(const char *, unsigned);
|
||||
int mkfifoat(int, const char *, unsigned);
|
||||
int mknod(const char *, unsigned, uint64_t);
|
||||
int mknodat(int, const char *, int, uint64_t);
|
||||
int makedirs(const char *, unsigned);
|
||||
int mkfifo(const char *, uint32_t);
|
||||
int mkfifoat(int, const char *, uint32_t);
|
||||
int mknod(const char *, uint32_t, uint64_t);
|
||||
int mknodat(int, const char *, int32_t, uint64_t);
|
||||
int sys_mlock(const void *, size_t);
|
||||
int sys_mlock2(const void *, size_t, int);
|
||||
int sys_mlockall(int);
|
||||
int sys_munlock(const void *, size_t);
|
||||
int sys_munlockall(void);
|
||||
int nice(int);
|
||||
int open(const char *, int, ...);
|
||||
int openat(int, const char *, int, ...);
|
||||
@@ -150,19 +161,19 @@ int renameat2(long, const char *, long, const char *, int);
|
||||
int rmdir(const char *);
|
||||
int sched_yield(void);
|
||||
int seccomp(unsigned, unsigned, void *);
|
||||
int setegid(unsigned);
|
||||
int seteuid(unsigned);
|
||||
int setegid(uint32_t);
|
||||
int seteuid(uint32_t);
|
||||
int setfsgid(unsigned);
|
||||
int setfsuid(unsigned);
|
||||
int setgid(unsigned);
|
||||
int setgroups(size_t, const unsigned[]);
|
||||
int setgroups(size_t, const uint32_t[]);
|
||||
int setpgid(int, int);
|
||||
int setpgrp(void);
|
||||
int setpriority(int, unsigned, int);
|
||||
int setregid(unsigned, unsigned);
|
||||
int setresgid(unsigned, unsigned, unsigned);
|
||||
int setresuid(unsigned, unsigned, unsigned);
|
||||
int setreuid(unsigned, unsigned);
|
||||
int setregid(uint32_t, uint32_t);
|
||||
int setresgid(uint32_t, uint32_t, uint32_t);
|
||||
int setresuid(uint32_t, uint32_t, uint32_t);
|
||||
int setreuid(uint32_t, uint32_t);
|
||||
int setsid(void);
|
||||
int setuid(unsigned);
|
||||
int sigignore(int);
|
||||
@@ -170,22 +181,16 @@ int siginterrupt(int, int);
|
||||
int symlink(const char *, const char *);
|
||||
int symlinkat(const char *, int, const char *);
|
||||
int sync_file_range(int, int64_t, int64_t, unsigned);
|
||||
int sys_iopl(int);
|
||||
int sys_mlock(const void *, size_t);
|
||||
int sys_mlock2(const void *, size_t, int);
|
||||
int sys_mlockall(int);
|
||||
int sys_munlock(const void *, size_t);
|
||||
int sys_munlockall(void);
|
||||
int sys_ptrace(int, ...);
|
||||
int sys_sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
|
||||
int tcgetpgrp(int);
|
||||
int tcsetpgrp(int, int);
|
||||
int tcsetpgrp(int, int32_t);
|
||||
int tgkill(int, int, int);
|
||||
int tkill(int, int);
|
||||
int tmpfd(void);
|
||||
int touch(const char *, unsigned);
|
||||
int touch(const char *, uint32_t);
|
||||
int truncate(const char *, int64_t);
|
||||
int ttyname_r(int, char *, size_t);
|
||||
unsigned umask(unsigned);
|
||||
int unlink(const char *);
|
||||
int unlink_s(const char **);
|
||||
int unlinkat(int, const char *, int);
|
||||
@@ -194,10 +199,11 @@ int usleep(unsigned);
|
||||
int vfork(void) returnstwice;
|
||||
int wait(int *);
|
||||
int waitpid(int, int *, int);
|
||||
int32_t tcgetpgrp(int);
|
||||
intptr_t syscall(int, ...);
|
||||
long ptrace(int, ...);
|
||||
ssize_t copy_file_range(int, long *, int, long *, size_t, unsigned);
|
||||
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, unsigned);
|
||||
ssize_t copy_file_range(int, long *, int, long *, size_t, uint32_t);
|
||||
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, uint32_t);
|
||||
ssize_t getfiledescriptorsize(int);
|
||||
ssize_t lseek(int, int64_t, int);
|
||||
ssize_t pread(int, void *, size_t, int64_t);
|
||||
@@ -206,13 +212,8 @@ ssize_t read(int, void *, size_t);
|
||||
ssize_t readansi(int, char *, size_t);
|
||||
ssize_t readlink(const char *, char *, size_t);
|
||||
ssize_t readlinkat(int, const char *, char *, size_t);
|
||||
ssize_t splice(int, int64_t *, int, int64_t *, size_t, unsigned);
|
||||
ssize_t splice(int, int64_t *, int, int64_t *, size_t, uint32_t);
|
||||
ssize_t write(int, const void *, size_t);
|
||||
unsigned getegid(void) nosideeffect;
|
||||
unsigned geteuid(void) nosideeffect;
|
||||
unsigned getgid(void) nosideeffect;
|
||||
unsigned getuid(void) libcesque;
|
||||
unsigned umask(unsigned);
|
||||
void sync(void);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
|
||||
+16
-10
@@ -121,12 +121,21 @@ o/$(MODE)/libc/calls/execlp.o \
|
||||
o/$(MODE)/libc/calls/statfs.o \
|
||||
o/$(MODE)/libc/calls/fstatfs.o \
|
||||
o/$(MODE)/libc/calls/execve-sysv.o \
|
||||
o/$(MODE)/libc/calls/readlinkat-nt.o \
|
||||
o/$(MODE)/libc/calls/execve-nt.greg.o \
|
||||
o/$(MODE)/libc/calls/mkntenvblock.o: private \
|
||||
OVERRIDE_CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
||||
# we must disable static stack safety because:
|
||||
# PATH_MAX*sizeof(char16_t)*2 exceeds 4096 byte frame limit
|
||||
o/$(MODE)/libc/calls/copyfile.o \
|
||||
o/$(MODE)/libc/calls/symlinkat-nt.o \
|
||||
o/$(MODE)/libc/calls/readlinkat-nt.o \
|
||||
o/$(MODE)/libc/calls/linkat-nt.o \
|
||||
o/$(MODE)/libc/calls/renameat-nt.o: private \
|
||||
OVERRIDE_CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
||||
# we must segregate codegen because:
|
||||
# file contains multiple independently linkable apis
|
||||
o/$(MODE)/libc/calls/ioctl-siocgifconf.o \
|
||||
@@ -170,15 +179,12 @@ o//libc/calls/statfs2cosmo.o: private \
|
||||
# we always want -O2 because:
|
||||
# division is expensive if not optimized
|
||||
o/$(MODE)/libc/calls/clock.o \
|
||||
o/$(MODE)/libc/calls/timespec_tomillis.o \
|
||||
o/$(MODE)/libc/calls/timespec_tomicros.o \
|
||||
o/$(MODE)/libc/calls/timespec_totimeval.o \
|
||||
o/$(MODE)/libc/calls/timespec_fromnanos.o \
|
||||
o/$(MODE)/libc/calls/timespec_frommillis.o \
|
||||
o/$(MODE)/libc/calls/timespec_frommicros.o \
|
||||
o/$(MODE)/libc/calls/timeval_tomillis.o \
|
||||
o/$(MODE)/libc/calls/timeval_frommillis.o \
|
||||
o/$(MODE)/libc/calls/timeval_frommicros.o: private \
|
||||
o/$(MODE)/libc/calls/_timespec_tomillis.o \
|
||||
o/$(MODE)/libc/calls/_timespec_tomicros.o \
|
||||
o/$(MODE)/libc/calls/_timespec_totimeval.o \
|
||||
o/$(MODE)/libc/calls/_timespec_fromnanos.o \
|
||||
o/$(MODE)/libc/calls/_timespec_frommillis.o \
|
||||
o/$(MODE)/libc/calls/_timespec_frommicros.o: private \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-O2
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2021 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 │
|
||||
@@ -16,14 +16,13 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
const char *GetCpuidEmulator(void) {
|
||||
static bool once;
|
||||
static char s[13];
|
||||
if (!once) {
|
||||
GetCpuidBrand(s, 0x40000000);
|
||||
once = true;
|
||||
uint32_t cfgetispeed(const struct termios *t) {
|
||||
if (CBAUD) {
|
||||
return t->c_cflag & CBAUD;
|
||||
} else {
|
||||
return t->c_ispeed;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2021 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 │
|
||||
@@ -16,14 +16,13 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
const char *GetCpuidOs(void) {
|
||||
static bool once;
|
||||
static char s[13];
|
||||
if (!once) {
|
||||
GetCpuidBrand(s, 0x40031337);
|
||||
once = true;
|
||||
uint32_t cfgetospeed(const struct termios *t) {
|
||||
if (CBAUD) {
|
||||
return t->c_cflag & CBAUD;
|
||||
} else {
|
||||
return t->c_ospeed;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int cfsetispeed(struct termios *t, unsigned speed) {
|
||||
if (speed) {
|
||||
if (CBAUD) {
|
||||
if (speed & ~CBAUD) return einval();
|
||||
t->c_cflag &= ~CBAUD;
|
||||
t->c_cflag |= speed;
|
||||
} else {
|
||||
t->c_ispeed = speed;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int cfsetospeed(struct termios *t, unsigned speed) {
|
||||
if (CBAUD) {
|
||||
if (!(speed & ~CBAUD)) {
|
||||
t->c_cflag &= ~CBAUD;
|
||||
t->c_cflag |= speed;
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
} else {
|
||||
t->c_ospeed = speed;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Returns input baud rate.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
uint32_t cfgetispeed(const struct termios *t) {
|
||||
if (CBAUD) {
|
||||
return t->c_cflag & CBAUD;
|
||||
} else {
|
||||
return t->c_ispeed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns output baud rate.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
uint32_t cfgetospeed(const struct termios *t) {
|
||||
if (CBAUD) {
|
||||
return t->c_cflag & CBAUD;
|
||||
} else {
|
||||
return t->c_ospeed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets input baud rate.
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int cfsetispeed(struct termios *t, unsigned speed) {
|
||||
if (speed) {
|
||||
if (CBAUD) {
|
||||
if (!(speed & ~CBAUD)) {
|
||||
t->c_cflag &= ~CBAUD;
|
||||
t->c_cflag |= speed;
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
} else {
|
||||
t->c_ispeed = speed;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets output baud rate.
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int cfsetospeed(struct termios *t, unsigned speed) {
|
||||
if (CBAUD) {
|
||||
if (!(speed & ~CBAUD)) {
|
||||
t->c_cflag &= ~CBAUD;
|
||||
t->c_cflag |= speed;
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
} else {
|
||||
t->c_ospeed = speed;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -36,7 +36,7 @@
|
||||
int chdir(const char *path) {
|
||||
int rc;
|
||||
GetProgramExecutableName(); // XXX: ugly workaround
|
||||
if (!path || (IsAsan() && !__asan_is_valid_str(path))) {
|
||||
if (!path || (IsAsan() && !__asan_is_valid(path, 1))) {
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_chdir(path);
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@
|
||||
*/
|
||||
int chroot(const char *path) {
|
||||
int rc;
|
||||
if (!path || (IsAsan() && !__asan_is_valid_str(path))) {
|
||||
if (!path || (IsAsan() && !__asan_is_valid(path, 1))) {
|
||||
rc = efault();
|
||||
} else {
|
||||
rc = sys_chroot(path);
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ int64_t clock(void) {
|
||||
if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == -1) {
|
||||
errno = e;
|
||||
if (getrusage(RUSAGE_SELF, &ru) != -1) {
|
||||
ts = timeval_totimespec(timeval_add(ru.ru_utime, ru.ru_stime));
|
||||
ts = _timeval_totimespec(_timeval_add(ru.ru_utime, ru.ru_stime));
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
static struct {
|
||||
pthread_once_t once;
|
||||
@@ -30,7 +30,7 @@ static struct {
|
||||
} g_mono;
|
||||
|
||||
static void sys_clock_gettime_mono_init(void) {
|
||||
g_mono.base_wall = timespec_real();
|
||||
g_mono.base_wall = _timespec_real();
|
||||
g_mono.base_tick = rdtsc();
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ int sys_clock_gettime_mono(struct timespec *time) {
|
||||
pthread_once(&g_mono.once, sys_clock_gettime_mono_init);
|
||||
cycles = rdtsc() - g_mono.base_tick;
|
||||
nanos = cycles / 3;
|
||||
*time = timespec_add(g_mono.base_wall, timespec_fromnanos(nanos));
|
||||
*time = _timespec_add(g_mono.base_wall, _timespec_fromnanos(nanos));
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
|
||||
+16
-19
@@ -50,23 +50,20 @@
|
||||
* sys_clock_gettime l: 220𝑐 71𝑛𝑠
|
||||
*
|
||||
* @param clock can be one of:
|
||||
* - `CLOCK_REALTIME`: universally supported
|
||||
* - `CLOCK_REALTIME_FAST`: ditto but faster on freebsd
|
||||
* - `CLOCK_REALTIME_PRECISE`: ditto but better on freebsd
|
||||
* - `CLOCK_REALTIME_COARSE`: : like `CLOCK_REALTIME_FAST` w/ Linux 2.6.32+
|
||||
* - `CLOCK_MONOTONIC`: universally supported
|
||||
* - `CLOCK_MONOTONIC_FAST`: ditto but faster on freebsd
|
||||
* - `CLOCK_MONOTONIC_PRECISE`: ditto but better on freebsd
|
||||
* - `CLOCK_MONOTONIC_COARSE`: : like `CLOCK_MONOTONIC_FAST` w/ Linux 2.6.32+
|
||||
* - `CLOCK_MONOTONIC_RAW`: is actually monotonic but needs Linux 2.6.28+
|
||||
* - `CLOCK_PROCESS_CPUTIME_ID`: linux and bsd
|
||||
* - `CLOCK_THREAD_CPUTIME_ID`: linux and bsd
|
||||
* - `CLOCK_MONOTONIC_COARSE`: linux, freebsd
|
||||
* - `CLOCK_PROF`: linux and netbsd
|
||||
* - `CLOCK_BOOTTIME`: linux and openbsd
|
||||
* - `CLOCK_REALTIME_ALARM`: linux-only
|
||||
* - `CLOCK_BOOTTIME_ALARM`: linux-only
|
||||
* - `CLOCK_TAI`: linux-only
|
||||
* - `CLOCK_REALTIME`: universally supported
|
||||
* - `CLOCK_REALTIME_FAST`: ditto but faster on freebsd
|
||||
* - `CLOCK_MONOTONIC`: universally supported
|
||||
* - `CLOCK_MONOTONIC_FAST`: ditto but faster on freebsd
|
||||
* - `CLOCK_MONOTONIC_RAW`: nearly universally supported
|
||||
* - `CLOCK_PROCESS_CPUTIME_ID`: linux and bsd
|
||||
* - `CLOCK_THREAD_CPUTIME_ID`: linux and bsd
|
||||
* - `CLOCK_REALTIME_COARSE`: : linux and openbsd
|
||||
* - `CLOCK_MONOTONIC_COARSE`: linux
|
||||
* - `CLOCK_PROF`: linux and netbsd
|
||||
* - `CLOCK_BOOTTIME`: linux and openbsd
|
||||
* - `CLOCK_REALTIME_ALARM`: linux-only
|
||||
* - `CLOCK_BOOTTIME_ALARM`: linux-only
|
||||
* - `CLOCK_TAI`: linux-only
|
||||
* @param ts is where the result is stored
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @error EPERM if pledge() is in play without stdio promise
|
||||
@@ -87,7 +84,7 @@ int clock_gettime(int clock, struct timespec *ts) {
|
||||
rc = __clock_gettime(clock, ts);
|
||||
}
|
||||
#if SYSDEBUG
|
||||
if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
|
||||
if (!(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
|
||||
STRACE("clock_gettime(%s, [%s]) → %d% m", DescribeClockName(clock),
|
||||
DescribeTimespec(rc, ts), rc);
|
||||
}
|
||||
@@ -119,7 +116,7 @@ clock_gettime_f *__clock_gettime_get(bool *opt_out_isfast) {
|
||||
return res;
|
||||
}
|
||||
|
||||
_Hide int __clock_gettime_init(int clockid, struct timespec *ts) {
|
||||
hidden int __clock_gettime_init(int clockid, struct timespec *ts) {
|
||||
clock_gettime_f *gettime;
|
||||
__clock_gettime = gettime = __clock_gettime_get(0);
|
||||
return gettime(clockid, ts);
|
||||
|
||||
@@ -7,9 +7,9 @@ COSMOPOLITAN_C_START_
|
||||
typedef int clock_gettime_f(int, struct timespec *);
|
||||
|
||||
extern clock_gettime_f *__clock_gettime;
|
||||
clock_gettime_f *__clock_gettime_get(bool *) _Hide;
|
||||
int __clock_gettime_init(int, struct timespec *) _Hide;
|
||||
int sys_clock_gettime_mono(struct timespec *) _Hide;
|
||||
clock_gettime_f *__clock_gettime_get(bool *) hidden;
|
||||
int __clock_gettime_init(int, struct timespec *) hidden;
|
||||
int sys_clock_gettime_mono(struct timespec *) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -33,24 +33,24 @@ textwindows int sys_clock_nanosleep_nt(int clock, int flags,
|
||||
abs = *req;
|
||||
for (;;) {
|
||||
if (sys_clock_gettime_nt(clock, &now)) return -1;
|
||||
if (timespec_cmp(now, abs) >= 0) return 0;
|
||||
if (_check_interrupts(false, g_fds.p)) return -1;
|
||||
if (_timespec_gte(now, abs)) return 0;
|
||||
if (_check_interrupts(false, g_fds.p)) return eintr();
|
||||
SleepEx(MIN(__SIG_POLLING_INTERVAL_MS,
|
||||
timespec_tomillis(timespec_sub(abs, now))),
|
||||
_timespec_tomillis(_timespec_sub(abs, now))),
|
||||
false);
|
||||
}
|
||||
} else {
|
||||
if (sys_clock_gettime_nt(clock, &now)) return -1;
|
||||
abs = timespec_add(now, *req);
|
||||
abs = _timespec_add(now, *req);
|
||||
for (;;) {
|
||||
sys_clock_gettime_nt(clock, &now);
|
||||
if (timespec_cmp(now, abs) >= 0) return 0;
|
||||
if (_timespec_gte(now, abs)) return 0;
|
||||
if (_check_interrupts(false, g_fds.p)) {
|
||||
if (rem) *rem = timespec_sub(abs, now);
|
||||
return -1;
|
||||
if (rem) *rem = _timespec_sub(abs, now);
|
||||
return eintr();
|
||||
}
|
||||
SleepEx(MIN(__SIG_POLLING_INTERVAL_MS,
|
||||
timespec_tomillis(timespec_sub(abs, now))),
|
||||
_timespec_tomillis(_timespec_sub(abs, now))),
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ int sys_clock_nanosleep_openbsd(int clock, int flags,
|
||||
res = sys_nanosleep(req, rem);
|
||||
} else {
|
||||
sys_clock_gettime(clock, &now);
|
||||
if (timespec_cmp(*req, now) > 0) {
|
||||
rel = timespec_sub(*req, now);
|
||||
if (_timespec_gt(*req, now)) {
|
||||
rel = _timespec_sub(*req, now);
|
||||
res = sys_nanosleep(&rel, 0);
|
||||
} else {
|
||||
res = 0;
|
||||
|
||||
@@ -31,10 +31,10 @@ int sys_clock_nanosleep_xnu(int clock, int flags, const struct timespec *req,
|
||||
struct timeval now, abs, rel;
|
||||
if (clock == CLOCK_REALTIME) {
|
||||
if (flags & TIMER_ABSTIME) {
|
||||
abs = timespec_totimeval(*req);
|
||||
abs = _timespec_totimeval(*req);
|
||||
sys_gettimeofday_xnu(&now, 0, 0);
|
||||
if (timeval_cmp(abs, now) > 0) {
|
||||
rel = timeval_sub(abs, now);
|
||||
if (_timeval_gt(abs, now)) {
|
||||
rel = _timeval_sub(abs, now);
|
||||
res = sys_select(0, 0, 0, 0, &rel);
|
||||
} else {
|
||||
res = 0;
|
||||
|
||||
+26
-170
@@ -16,12 +16,7 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/asan.internal.h"
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/clock_gettime.internal.h"
|
||||
#include "libc/calls/cp.internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timespec.internal.h"
|
||||
@@ -31,158 +26,11 @@
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/ntdll.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/consts/timer.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
static int64_t g_nanosleep_latency;
|
||||
|
||||
static errno_t sys_clock_nanosleep(int clock, int flags,
|
||||
const struct timespec *req,
|
||||
struct timespec *rem) {
|
||||
int e, rc;
|
||||
BEGIN_CANCELLATION_POINT;
|
||||
e = errno;
|
||||
if (IsLinux() || IsFreebsd() || IsNetbsd()) {
|
||||
rc = __sys_clock_nanosleep(clock, flags, req, rem);
|
||||
} else if (IsXnu()) {
|
||||
rc = sys_clock_nanosleep_xnu(clock, flags, req, rem);
|
||||
} else if (IsOpenbsd()) {
|
||||
rc = sys_clock_nanosleep_openbsd(clock, flags, req, rem);
|
||||
} else {
|
||||
rc = sys_clock_nanosleep_nt(clock, flags, req, rem);
|
||||
}
|
||||
if (rc == -1) {
|
||||
rc = errno;
|
||||
errno = e;
|
||||
}
|
||||
END_CANCELLATION_POINT;
|
||||
return rc;
|
||||
}
|
||||
|
||||
// determine sched_yield() vs. clock_nanosleep() threshold
|
||||
// 1ns sys_clock_nanosleep() on Windows takes milliseconds :'(
|
||||
// 1ns sys_clock_nanosleep() on Linux/FreeBSD takes tens of microseconds
|
||||
// 1ns sys_clock_nanosleep() on OpenBSD/NetBSD takes tens of milliseconds D:
|
||||
static struct timespec GetNanosleepLatency(void) {
|
||||
errno_t rc;
|
||||
int64_t nanos;
|
||||
clock_gettime_f *cgt;
|
||||
struct timespec x, y, w = {0, 1};
|
||||
if (!(nanos = g_nanosleep_latency)) {
|
||||
BLOCK_CANCELLATIONS;
|
||||
for (cgt = __clock_gettime_get(0);;) {
|
||||
_npassert(!cgt(CLOCK_REALTIME_PRECISE, &x));
|
||||
rc = sys_clock_nanosleep(CLOCK_REALTIME, 0, &w, 0);
|
||||
_npassert(!rc || rc == EINTR);
|
||||
if (!rc) {
|
||||
_npassert(!cgt(CLOCK_REALTIME_PRECISE, &y));
|
||||
nanos = timespec_tonanos(timespec_sub(y, x));
|
||||
g_nanosleep_latency = nanos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ALLOW_CANCELLATIONS;
|
||||
}
|
||||
return timespec_fromnanos(nanos);
|
||||
}
|
||||
|
||||
static errno_t CheckCancel(void) {
|
||||
if (_weaken(pthread_testcancel_np)) {
|
||||
return _weaken(pthread_testcancel_np)();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static errno_t SpinNanosleep(int clock, int flags, const struct timespec *req,
|
||||
struct timespec *rem) {
|
||||
errno_t rc;
|
||||
clock_gettime_f *cgt;
|
||||
struct timespec now, start, elapsed;
|
||||
if ((rc = CheckCancel())) {
|
||||
if (rc == EINTR && !flags && rem) {
|
||||
*rem = *req;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
cgt = __clock_gettime_get(0);
|
||||
_npassert(!cgt(CLOCK_REALTIME, &start));
|
||||
for (;;) {
|
||||
sched_yield();
|
||||
_npassert(!cgt(CLOCK_REALTIME, &now));
|
||||
if (flags & TIMER_ABSTIME) {
|
||||
if (timespec_cmp(now, *req) >= 0) {
|
||||
return 0;
|
||||
}
|
||||
if ((rc = CheckCancel())) {
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
if (timespec_cmp(now, start) < 0) continue;
|
||||
elapsed = timespec_sub(now, start);
|
||||
if ((rc = CheckCancel())) {
|
||||
if (rc == EINTR && rem) {
|
||||
if (timespec_cmp(elapsed, *req) >= 0) {
|
||||
bzero(rem, sizeof(*rem));
|
||||
} else {
|
||||
*rem = elapsed;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
if (timespec_cmp(elapsed, *req) >= 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool ShouldUseSpinNanosleep(int clock, int flags,
|
||||
const struct timespec *req) {
|
||||
errno_t e;
|
||||
struct timespec now;
|
||||
if (IsWindows()) {
|
||||
// Our spin technique here is intended to take advantage of the fact
|
||||
// that sched_yield() takes about a hundred nanoseconds. But Windows
|
||||
// SleepEx(0, 0) a.k.a. NtYieldExecution() takes a whole millisecond
|
||||
// and it matters not whether our intent is to yielding or sleeping,
|
||||
// since we use the SleepEx() function to implement both. Therefore,
|
||||
// there's no reason to use SpinNanosleep() on Windows.
|
||||
return false;
|
||||
}
|
||||
if (clock != CLOCK_REALTIME && //
|
||||
clock != CLOCK_REALTIME_PRECISE && //
|
||||
clock != CLOCK_MONOTONIC && //
|
||||
clock != CLOCK_MONOTONIC_RAW && //
|
||||
clock != CLOCK_MONOTONIC_PRECISE) {
|
||||
return false;
|
||||
}
|
||||
if (!flags) {
|
||||
return timespec_cmp(*req, GetNanosleepLatency()) < 0;
|
||||
}
|
||||
// We need a clock_gettime() system call to perform this check if the
|
||||
// sleep request is an absolute timestamp. So we avoid doing that on
|
||||
// systems where sleep latency isn't too outrageous.
|
||||
if (timespec_cmp(GetNanosleepLatency(), timespec_fromnanos(50 * 1000)) < 0) {
|
||||
return false;
|
||||
}
|
||||
e = errno;
|
||||
if (__clock_gettime_get(0)(clock, &now)) {
|
||||
// punt to the nanosleep system call
|
||||
errno = e;
|
||||
return false;
|
||||
}
|
||||
return timespec_cmp(*req, now) < 0 ||
|
||||
timespec_cmp(timespec_sub(*req, now), GetNanosleepLatency()) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sleeps for particular amount of time.
|
||||
*
|
||||
@@ -207,8 +55,8 @@ static bool ShouldUseSpinNanosleep(int clock, int flags,
|
||||
*
|
||||
* struct timespec rel, now, abs;
|
||||
* clock_gettime(CLOCK_REALTIME, &now);
|
||||
* rel = timespec_frommillis(100);
|
||||
* abs = timespec_add(now, rel);
|
||||
* rel = _timespec_frommillis(100);
|
||||
* abs = _timespec_add(now, rel);
|
||||
* while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &abs, 0));
|
||||
*
|
||||
* will accurately spin on `EINTR` errors. That way you're not impeding
|
||||
@@ -226,43 +74,51 @@ static bool ShouldUseSpinNanosleep(int clock, int flags,
|
||||
* if flags is `TIMER_ABSTIME` then `rem` is ignored
|
||||
* @return 0 on success, or errno on error
|
||||
* @raise EINTR when a signal got delivered while we were waiting
|
||||
* @raise ECANCELED if thread was cancelled in masked mode
|
||||
* @raise ENOTSUP if `clock` is known but we can't use it here
|
||||
* @raise EFAULT if `req` or null or bad memory was passed
|
||||
* @raise EINVAL if `clock` is unknown to current platform
|
||||
* @raise EINVAL if `flags` has an unrecognized value
|
||||
* @raise EINVAL if `req->tv_nsec ∉ [0,1000000000)`
|
||||
* @raise ENOSYS on bare metal
|
||||
* @cancellationpoint
|
||||
* @returnserrno
|
||||
* @norestart
|
||||
*/
|
||||
errno_t clock_nanosleep(int clock, int flags, const struct timespec *req,
|
||||
struct timespec *rem) {
|
||||
int rc;
|
||||
LOCKTRACE("clock_nanosleep(%s, %s, %s) → ...", DescribeClockName(clock),
|
||||
DescribeSleepFlags(flags), DescribeTimespec(0, req));
|
||||
if (IsMetal()) {
|
||||
rc = ENOSYS;
|
||||
} else if (!req || (IsAsan() && (!__asan_is_valid_timespec(req) ||
|
||||
(rem && !__asan_is_valid_timespec(rem))))) {
|
||||
rc = EFAULT;
|
||||
int rc, e = errno;
|
||||
|
||||
if (!req || (IsAsan() && (!__asan_is_valid_timespec(req) ||
|
||||
(rem && !__asan_is_valid_timespec(rem))))) {
|
||||
rc = efault();
|
||||
} else if (clock == 127 || //
|
||||
(flags & ~TIMER_ABSTIME) || //
|
||||
req->tv_sec < 0 || //
|
||||
!(0 <= req->tv_nsec && req->tv_nsec <= 999999999)) {
|
||||
rc = EINVAL;
|
||||
} else if (ShouldUseSpinNanosleep(clock, flags, req)) {
|
||||
rc = SpinNanosleep(clock, flags, req, rem);
|
||||
} else {
|
||||
rc = einval();
|
||||
} else if (IsLinux() || IsFreebsd() || IsNetbsd()) {
|
||||
rc = sys_clock_nanosleep(clock, flags, req, rem);
|
||||
} else if (IsXnu()) {
|
||||
rc = sys_clock_nanosleep_xnu(clock, flags, req, rem);
|
||||
} else if (IsOpenbsd()) {
|
||||
rc = sys_clock_nanosleep_openbsd(clock, flags, req, rem);
|
||||
} else if (IsMetal()) {
|
||||
rc = enosys();
|
||||
} else {
|
||||
rc = sys_clock_nanosleep_nt(clock, flags, req, rem);
|
||||
}
|
||||
|
||||
if (rc == -1) {
|
||||
rc = errno;
|
||||
errno = e;
|
||||
}
|
||||
|
||||
#if SYSDEBUG
|
||||
if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
|
||||
if (!(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
|
||||
STRACE("clock_nanosleep(%s, %s, %s, [%s]) → %s", DescribeClockName(clock),
|
||||
DescribeSleepFlags(flags), DescribeTimespec(0, req),
|
||||
DescribeTimespec(rc, rem), DescribeErrno(rc));
|
||||
DescribeTimespec(rc, rem), DescribeErrnoResult(rc));
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -18,22 +18,15 @@
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/nt/enum/filetype.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
||||
void sys_fcntl_nt_lock_cleanup(int) _Hide;
|
||||
|
||||
textwindows int sys_close_nt(struct Fd *fd, int fildes) {
|
||||
textwindows int sys_close_nt(struct Fd *fd) {
|
||||
int e;
|
||||
bool ok = true;
|
||||
|
||||
if (_weaken(sys_fcntl_nt_lock_cleanup)) {
|
||||
_weaken(sys_fcntl_nt_lock_cleanup)(fildes);
|
||||
}
|
||||
|
||||
if (fd->kind == kFdFile && ((fd->flags & O_ACCMODE) != O_RDONLY &&
|
||||
GetFileType(fd->handle) == kNtFileTypeDisk)) {
|
||||
// Like Linux, closing a file on Windows doesn't guarantee it's
|
||||
|
||||
+2
-2
@@ -16,10 +16,10 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/calls/syscall-nt.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
@@ -81,7 +81,7 @@ int close(int fd) {
|
||||
} else if (__isfdkind(fd, kFdFile) || //
|
||||
__isfdkind(fd, kFdConsole) || //
|
||||
__isfdkind(fd, kFdProcess)) { //
|
||||
rc = sys_close_nt(g_fds.p + fd, fd);
|
||||
rc = sys_close_nt(g_fds.p + fd);
|
||||
} else {
|
||||
rc = eio();
|
||||
}
|
||||
|
||||
@@ -27,9 +27,12 @@
|
||||
/**
|
||||
* Closes extra file descriptors, e.g.
|
||||
*
|
||||
* if (closefrom(3))
|
||||
* for (int i = 3; i < 256; ++i)
|
||||
* // close all non-stdio file descriptors
|
||||
* if (closefrom(3) == -1) {
|
||||
* for (int i = 3; i < 256; ++i) {
|
||||
* close(i);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @raise EBADF if `first` is negative
|
||||
@@ -37,7 +40,6 @@
|
||||
* @raise EBADF on OpenBSD if `first` is greater than highest fd
|
||||
* @raise EINVAL if flags are bad or first is greater than last
|
||||
* @raise EMFILE if a weird race condition happens on Linux
|
||||
* @raise ECANCELED if thread was cancelled in masked mode
|
||||
* @raise EINTR possibly on OpenBSD
|
||||
* @raise ENOMEM on Linux maybe
|
||||
*/
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/cp.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
@@ -41,7 +39,6 @@ static bool HasCopyFileRange(void) {
|
||||
bool ok;
|
||||
int e, rc;
|
||||
e = errno;
|
||||
BLOCK_CANCELLATIONS;
|
||||
if (IsLinux()) {
|
||||
// We modernize our detection by a few years for simplicity.
|
||||
// This system call is chosen since it's listed by pledge().
|
||||
@@ -52,7 +49,6 @@ static bool HasCopyFileRange(void) {
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
ALLOW_CANCELLATIONS;
|
||||
errno = e;
|
||||
return ok;
|
||||
}
|
||||
@@ -85,7 +81,6 @@ static void copy_file_range_init(void) {
|
||||
* @raise EBADF if `infd` or `outfd` aren't open files or append-only
|
||||
* @raise EPERM if `fdout` refers to an immutable file on Linux
|
||||
* @raise ENOTSUP if `infd` or `outfd` is a zip file descriptor
|
||||
* @raise ECANCELED if thread was cancelled in masked mode
|
||||
* @raise EINVAL if ranges overlap or `flags` is non-zero
|
||||
* @raise EFBIG if `setrlimit(RLIMIT_FSIZE)` is exceeded
|
||||
* @raise EFAULT if one of the pointers memory is bad
|
||||
@@ -98,15 +93,12 @@ static void copy_file_range_init(void) {
|
||||
* @raise EIO if a low-level i/o error happens
|
||||
* @see sendfile() for seekable → socket
|
||||
* @see splice() for fd ↔ pipe
|
||||
* @cancellationpoint
|
||||
*/
|
||||
ssize_t copy_file_range(int infd, int64_t *opt_in_out_inoffset, int outfd,
|
||||
int64_t *opt_in_out_outoffset, size_t uptobytes,
|
||||
uint32_t flags) {
|
||||
ssize_t rc;
|
||||
pthread_once(&g_copy_file_range.once, copy_file_range_init);
|
||||
BEGIN_CANCELLATION_POINT;
|
||||
|
||||
if (!g_copy_file_range.ok) {
|
||||
rc = enosys();
|
||||
} else if (IsAsan() && ((opt_in_out_inoffset &&
|
||||
@@ -120,8 +112,6 @@ ssize_t copy_file_range(int infd, int64_t *opt_in_out_inoffset, int outfd,
|
||||
rc = sys_copy_file_range(infd, opt_in_out_inoffset, outfd,
|
||||
opt_in_out_outoffset, uptobytes, flags);
|
||||
}
|
||||
|
||||
END_CANCELLATION_POINT;
|
||||
STRACE("copy_file_range(%d, %s, %d, %s, %'zu, %#x) → %'ld% m", infd,
|
||||
DescribeInOutInt64(rc, opt_in_out_inoffset), outfd,
|
||||
DescribeInOutInt64(rc, opt_in_out_outoffset), uptobytes, flags);
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 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 "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/cp.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#ifdef MODE_DBG
|
||||
|
||||
int begin_cancellation_point(void) {
|
||||
int state = 0;
|
||||
struct CosmoTib *tib;
|
||||
struct PosixThread *pt;
|
||||
if (__enable_tls) {
|
||||
tib = __get_tls();
|
||||
if ((pt = (struct PosixThread *)tib->tib_pthread)) {
|
||||
state = pt->flags & PT_INCANCEL;
|
||||
pt->flags |= PT_INCANCEL;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
void end_cancellation_point(int state) {
|
||||
struct CosmoTib *tib;
|
||||
struct PosixThread *pt;
|
||||
if (__enable_tls) {
|
||||
tib = __get_tls();
|
||||
if ((pt = (struct PosixThread *)tib->tib_pthread)) {
|
||||
pt->flags &= ~PT_INCANCEL;
|
||||
pt->flags |= state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void report_cancellation_point(void) {
|
||||
BLOCK_CANCELLATIONS;
|
||||
_bt("error: need BEGIN/END_CANCELLATION_POINT\n");
|
||||
ALLOW_CANCELLATIONS;
|
||||
}
|
||||
|
||||
#endif /* MODE_DBG */
|
||||
@@ -1,25 +0,0 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_CP_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_CP_INTERNAL_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int begin_cancellation_point(void);
|
||||
void end_cancellation_point(int);
|
||||
|
||||
#ifndef MODE_DBG
|
||||
#define BEGIN_CANCELLATION_POINT (void)0
|
||||
#define END_CANCELLATION_POINT (void)0
|
||||
#else
|
||||
#define BEGIN_CANCELLATION_POINT \
|
||||
do { \
|
||||
int _Cp; \
|
||||
_Cp = begin_cancellation_point()
|
||||
#define END_CANCELLATION_POINT \
|
||||
end_cancellation_point(_Cp); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_CP_INTERNAL_H_ */
|
||||
@@ -31,7 +31,6 @@
|
||||
* @param mode is octal bits, e.g. 0644 usually
|
||||
* @return file descriptor, or -1 w/ errno
|
||||
* @see openat() for further documentation
|
||||
* @cancellationpoint
|
||||
* @asyncsignalsafe
|
||||
* @restartable
|
||||
* @threadsafe
|
||||
|
||||
+25
-14
@@ -31,11 +31,13 @@
|
||||
// Implements dup(), dup2(), dup3(), and F_DUPFD for Windows.
|
||||
textwindows int sys_dup_nt(int oldfd, int newfd, int flags, int start) {
|
||||
int64_t rc, proc, handle;
|
||||
_unassert(oldfd >= 0);
|
||||
_unassert(newfd >= -1);
|
||||
_unassert(!(flags & ~O_CLOEXEC));
|
||||
|
||||
__fds_lock();
|
||||
|
||||
if (!__isfdopen(oldfd) || newfd < -1 ||
|
||||
if (oldfd >= g_fds.n ||
|
||||
(g_fds.p[oldfd].kind != kFdFile && g_fds.p[oldfd].kind != kFdSocket &&
|
||||
g_fds.p[oldfd].kind != kFdConsole)) {
|
||||
__fds_unlock();
|
||||
@@ -43,18 +45,27 @@ textwindows int sys_dup_nt(int oldfd, int newfd, int flags, int start) {
|
||||
}
|
||||
|
||||
// allocate a new file descriptor
|
||||
if (newfd == -1) {
|
||||
if ((newfd = __reservefd_unlocked(start)) == -1) {
|
||||
__fds_unlock();
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (__ensurefds_unlocked(newfd) == -1) {
|
||||
__fds_unlock();
|
||||
return -1;
|
||||
}
|
||||
if (g_fds.p[newfd].kind) {
|
||||
sys_close_nt(g_fds.p + newfd, newfd);
|
||||
for (;;) {
|
||||
if (newfd == -1) {
|
||||
if ((newfd = __reservefd_unlocked(start)) == -1) {
|
||||
__fds_unlock();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
if (__ensurefds_unlocked(newfd) == -1) {
|
||||
__fds_unlock();
|
||||
return -1;
|
||||
}
|
||||
if (g_fds.p[newfd].kind) {
|
||||
__fds_unlock();
|
||||
close(newfd);
|
||||
__fds_lock();
|
||||
}
|
||||
if (!g_fds.p[newfd].kind) {
|
||||
g_fds.p[newfd].kind = kFdReserved;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +86,7 @@ textwindows int sys_dup_nt(int oldfd, int newfd, int flags, int start) {
|
||||
}
|
||||
rc = newfd;
|
||||
} else {
|
||||
__releasefd(newfd);
|
||||
__releasefd_unlocked(newfd);
|
||||
rc = __winerr();
|
||||
}
|
||||
|
||||
|
||||
+24
-37
@@ -16,8 +16,6 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/blocksigs.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
@@ -41,17 +39,12 @@ static bool IsApeBinary(const char *path) {
|
||||
int fd;
|
||||
char buf[8];
|
||||
bool res = false;
|
||||
// TODO(jart): Should we block signals too?
|
||||
BLOCK_CANCELLATIONS;
|
||||
if ((fd = sys_open(path, O_RDONLY, 0)) != -1) {
|
||||
if (sys_read(fd, buf, 8) == 8 && //
|
||||
(READ64LE(buf) == READ64LE("MZqFpD='") ||
|
||||
READ64LE(buf) == READ64LE("JTqFpD='"))) {
|
||||
if (sys_read(fd, buf, 8) == 8 && READ64LE(buf) == READ64LE("MZqFpD='")) {
|
||||
res = true;
|
||||
}
|
||||
sys_close(fd);
|
||||
}
|
||||
ALLOW_CANCELLATIONS;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -68,41 +61,35 @@ static const char *Join(const char *a, const char *b, char buf[PATH_MAX]) {
|
||||
}
|
||||
|
||||
int sys_execve(const char *prog, char *const argv[], char *const envp[]) {
|
||||
int e;
|
||||
size_t i;
|
||||
int e, rc;
|
||||
char *buf;
|
||||
char **shargs;
|
||||
const char *ape;
|
||||
e = errno;
|
||||
__sys_execve(prog, argv, envp);
|
||||
if (errno == ENOEXEC) {
|
||||
for (i = 0; argv[i];) ++i;
|
||||
buf = alloca(PATH_MAX);
|
||||
shargs = alloca((i + 4) * sizeof(char *));
|
||||
if (IsApeBinary(prog) &&
|
||||
(CanExecute((ape = "/usr/bin/ape")) ||
|
||||
CanExecute((ape = Join(firstnonnull(getenv("TMPDIR"),
|
||||
firstnonnull(getenv("HOME"), ".")),
|
||||
".ape", buf))) ||
|
||||
CanExecute(
|
||||
(ape = Join(firstnonnull(getenv("HOME"), "."), ".ape", buf))))) {
|
||||
shargs[0] = ape;
|
||||
shargs[1] = "-";
|
||||
shargs[2] = prog;
|
||||
memcpy(shargs + 3, argv, (i + 1) * sizeof(char *));
|
||||
errno = e;
|
||||
rc = __sys_execve(shargs[0], shargs, envp);
|
||||
} else if (CanExecute(prog)) {
|
||||
shargs[0] = _PATH_BSHELL;
|
||||
shargs[1] = prog;
|
||||
memcpy(shargs + 2, argv + 1, i * sizeof(char *));
|
||||
errno = e;
|
||||
rc = __sys_execve(shargs[0], shargs, envp);
|
||||
} else {
|
||||
rc = enoexec();
|
||||
}
|
||||
if (errno != ENOEXEC) return -1;
|
||||
for (i = 0; argv[i];) ++i;
|
||||
buf = alloca(PATH_MAX);
|
||||
shargs = alloca((i + 4) * sizeof(char *));
|
||||
if (IsApeBinary(prog) &&
|
||||
(CanExecute((ape = "/usr/bin/ape")) ||
|
||||
CanExecute((ape = Join(firstnonnull(getenv("TMPDIR"),
|
||||
firstnonnull(getenv("HOME"), ".")),
|
||||
".ape", buf))) ||
|
||||
CanExecute(
|
||||
(ape = Join(firstnonnull(getenv("HOME"), "."), ".ape", buf))))) {
|
||||
shargs[0] = ape;
|
||||
shargs[1] = "-";
|
||||
shargs[2] = prog;
|
||||
memcpy(shargs + 3, argv, (i + 1) * sizeof(char *));
|
||||
} else if (CanExecute(prog)) {
|
||||
shargs[0] = _PATH_BSHELL;
|
||||
shargs[1] = prog;
|
||||
memcpy(shargs + 2, argv + 1, i * sizeof(char *));
|
||||
} else {
|
||||
rc = -1;
|
||||
return enoexec();
|
||||
}
|
||||
return rc;
|
||||
errno = e;
|
||||
return __sys_execve(shargs[0], shargs, envp);
|
||||
}
|
||||
Loaded 100 of 1504 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user