mirror of
https://github.com/jart/cosmopolitan.git
synced 2026-11-08 08:08:04 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
497d4fa6d1 | ||
|
|
614229e3f4 | ||
|
|
1a839ba41d | ||
|
|
4a6be2154d | ||
|
|
3e702e8f65 | ||
|
|
a8ff220654 | ||
|
|
d484e1dbd4 | ||
|
|
d5b8b644c2 | ||
|
|
f7bccf5513 | ||
|
|
6758c3f400 | ||
|
|
9a5d69c842 | ||
|
|
12e07798df | ||
|
|
9c6d78c26d | ||
|
|
221adfa606 | ||
|
|
4ad4c2625d | ||
|
|
e3eb55cc8f | ||
|
|
36f52ea687 | ||
|
|
669b4c5f19 | ||
|
|
ba42248575 | ||
|
|
999481ace0 | ||
|
|
7f925e6be9 | ||
|
|
2f4335e081 | ||
|
|
0adefbf152 | ||
|
|
a412ca7a77 | ||
|
|
426d441994 | ||
|
|
4f39139fe0 | ||
|
|
0d084d01b9 | ||
|
|
390aee960a | ||
|
|
792b1c84c0 | ||
|
|
2d6ea2fbc9 | ||
|
|
58b2f9bd6b | ||
|
|
893703a07b | ||
|
|
775f456d4c | ||
|
|
e2f429b742 | ||
|
|
ba180e754d | ||
|
|
713d4424c6 | ||
|
|
e16b969829 | ||
|
|
2112fb1736 | ||
|
|
2aa044cb0c | ||
|
|
c8a9d3458e | ||
|
|
c5de653b98 | ||
|
|
22fcab131c | ||
|
|
da7c8c7b54 | ||
|
|
f5520209f5 | ||
|
|
ae365928c5 | ||
|
|
5923d483a4 | ||
|
|
0312898979 | ||
|
|
db16f0129a | ||
|
|
c395d16230 | ||
|
|
1011db793f | ||
|
|
ca88fc34c3 | ||
|
|
ad97d7b9db | ||
|
|
18a24935cc | ||
|
|
8b69acc1cc | ||
|
|
0468ca02fe | ||
|
|
7355499a6a | ||
|
|
1208ac9f10 | ||
|
|
298ba74a45 | ||
|
|
b15f9eb58f | ||
|
|
60eb34509b | ||
|
|
a808b3e738 | ||
|
|
0f1ead8943 | ||
|
|
dfabcd84c1 | ||
|
|
71d955be1d | ||
|
|
e4ee1da652 | ||
|
|
ff9c15f48a | ||
|
|
b275e664ec | ||
|
|
e323527ffa | ||
|
|
08fef9b277 | ||
|
|
94dcf81954 | ||
|
|
2b6261a52d | ||
|
|
0eb621f75e | ||
|
|
9634227181 | ||
|
|
9fce2751c8 | ||
|
|
49c1dea03b | ||
|
|
4b8874ceb9 | ||
|
|
cf19e3e46a | ||
|
|
1429a7b3ef | ||
|
|
7486a2cd51 | ||
|
|
fd0da9c0df | ||
|
|
6d36584ff2 | ||
|
|
f422edaf15 | ||
|
|
1473eafd1a | ||
|
|
cac86197cb | ||
|
|
006c44ff5d | ||
|
|
be3e109309 | ||
|
|
2bad436abf | ||
|
|
7ab4630cc9 | ||
|
|
5dab97b6d4 | ||
|
|
b38a442386 | ||
|
|
0708310041 | ||
|
|
cd27a53345 | ||
|
|
416e173448 | ||
|
|
d73523864a | ||
|
|
eb69a42863 | ||
|
|
651826b660 | ||
|
|
6dcdf91458 | ||
|
|
a6586cafb2 | ||
|
|
e496ee7a80 | ||
|
|
a4b6803556 | ||
|
|
9c72fef086 | ||
|
|
10d1c6da18 | ||
|
|
5ed84e04f8 | ||
|
|
25fa6acc4d | ||
|
|
9a46c5afc4 | ||
|
|
97ae5f7b1e | ||
|
|
1c7c277432 | ||
|
|
70ca8c4016 | ||
|
|
73507d5f4e | ||
|
|
d2f811eff3 | ||
|
|
2e5181666f | ||
|
|
5c0ce6b83e | ||
|
|
f6b3019796 | ||
|
|
dd04aeba1c | ||
|
|
57c0dcdc29 | ||
|
|
6d39c6f646 | ||
|
|
5a3c646307 | ||
|
|
0da47c51de | ||
|
|
120079b0a6 | ||
|
|
3da887c58f | ||
|
|
4922bc4890 | ||
|
|
ed161b240e | ||
|
|
531bfbd61f | ||
|
|
cd0b12ed1a | ||
|
|
0dc0758574 | ||
|
|
bcae817215 | ||
|
|
b850b14300 | ||
|
|
a277170c9a | ||
|
|
711bd095db | ||
|
|
d55b019284 | ||
|
|
f2af97711b | ||
|
|
b46ac13504 | ||
|
|
cee6871710 | ||
|
|
b74d8c1acd | ||
|
|
fc595a7111 | ||
|
|
bf7843833f | ||
|
|
251dcb07eb | ||
|
|
b407327972 | ||
|
|
aee50b1327 | ||
|
|
4de2cf34e6 |
No files matched your search
@@ -8,6 +8,7 @@ AlwaysBreakBeforeMultilineStrings: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
IncludeBlocks: Merge
|
||||
---
|
||||
Language: Cpp
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
# build/config.mk
|
||||
|
||||
SHELL = build/bootstrap/cocmd.com
|
||||
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win10 win10:31336
|
||||
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win10
|
||||
MAKEFLAGS += --no-builtin-rules
|
||||
|
||||
.SUFFIXES:
|
||||
@@ -121,6 +121,7 @@ include libc/tinymath/tinymath.mk # │ You can issue raw system calls
|
||||
include third_party/compiler_rt/compiler_rt.mk # │
|
||||
include libc/str/str.mk # │
|
||||
include third_party/xed/xed.mk # │
|
||||
include third_party/puff/puff.mk # │
|
||||
include third_party/zlib/zlib.mk # │
|
||||
include third_party/double-conversion/dc.mk # │
|
||||
include libc/elf/elf.mk # │
|
||||
@@ -134,11 +135,11 @@ include libc/crt/crt.mk # │ You can issue system calls
|
||||
include third_party/nsync/nsync.mk # │
|
||||
include third_party/dlmalloc/dlmalloc.mk #─┘
|
||||
include libc/mem/mem.mk #─┐
|
||||
include libc/zipos/zipos.mk # ├──DYNAMIC RUNTIME
|
||||
include third_party/gdtoa/gdtoa.mk # │ You can now use stdio
|
||||
include libc/time/time.mk # │ You can finally call malloc()
|
||||
include third_party/nsync/mem/mem.mk # │
|
||||
include libc/thread/thread.mk # │
|
||||
include third_party/gdtoa/gdtoa.mk # ├──DYNAMIC RUNTIME
|
||||
include third_party/nsync/mem/mem.mk # │ You can now use stdio
|
||||
include libc/thread/thread.mk # │ You can finally call malloc()
|
||||
include libc/zipos/zipos.mk # │
|
||||
include libc/time/time.mk # │
|
||||
include libc/stdio/stdio.mk # │
|
||||
include third_party/libcxx/libcxx.mk # │
|
||||
include net/net.mk # │
|
||||
@@ -175,7 +176,9 @@ 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
|
||||
@@ -192,6 +195,7 @@ 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
|
||||
@@ -278,14 +282,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)
|
||||
TAGS: o/$(MODE)/srcs-old.txt $(SRCS) o/$(MODE)/third_party/ctags/ctags.com
|
||||
@$(RM) $@
|
||||
@$(TAGS) $(TAGSFLAGS) -L $< -o $@
|
||||
@o/$(MODE)/third_party/ctags/ctags.com $(TAGSFLAGS) -L $< -o $@
|
||||
|
||||
HTAGS: private .UNSANDBOXED = 1
|
||||
HTAGS: o/$(MODE)/hdrs-old.txt $(HDRS)
|
||||
HTAGS: o/$(MODE)/hdrs-old.txt $(HDRS) o/$(MODE)/third_party/ctags/ctags.com
|
||||
@$(RM) $@
|
||||
@build/htags -L $< -o $@
|
||||
@build/htags o/$(MODE)/third_party/ctags/ctags.com -L $< -o $@
|
||||
|
||||
loc: private .UNSANDBOXED = 1
|
||||
loc: o/$(MODE)/tool/build/summy.com
|
||||
@@ -306,7 +310,6 @@ COSMOPOLITAN_OBJECTS = \
|
||||
LIBC_LOG \
|
||||
LIBC_TIME \
|
||||
LIBC_ZIPOS \
|
||||
THIRD_PARTY_ZLIB \
|
||||
THIRD_PARTY_MUSL \
|
||||
LIBC_STDIO \
|
||||
THIRD_PARTY_GDTOA \
|
||||
@@ -332,6 +335,7 @@ COSMOPOLITAN_OBJECTS = \
|
||||
LIBC_NT_ADVAPI32 \
|
||||
LIBC_NT_SYNCHRONIZATION \
|
||||
LIBC_FMT \
|
||||
THIRD_PARTY_PUFF \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
LIBC_TINYMATH \
|
||||
THIRD_PARTY_XED \
|
||||
@@ -371,11 +375,9 @@ 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: \
|
||||
@@ -438,9 +440,9 @@ $(SRCS):
|
||||
$(HDRS):
|
||||
$(INCS):
|
||||
.DEFAULT:
|
||||
@$(ECHO) >&2
|
||||
@$(ECHO) NOTE: deleting o/$(MODE)/depend because of an unspecified prerequisite: $@ >&2
|
||||
@$(ECHO) >&2
|
||||
@$(ECHO)
|
||||
@$(ECHO) NOTE: deleting o/$(MODE)/depend because of an unspecified prerequisite: $@
|
||||
@$(ECHO)
|
||||
$(RM) o/$(MODE)/depend
|
||||
|
||||
-include o/$(MODE)/depend
|
||||
@@ -57,9 +57,13 @@ 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 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.
|
||||
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.
|
||||
|
||||
```sh
|
||||
# System-Wide APE Install
|
||||
@@ -239,6 +243,11 @@ You normally run the `.com.dbg` file under gdb. If you need to debug the
|
||||
gdb foo.com -ex 'add-symbol-file foo.com.dbg 0x401000'
|
||||
```
|
||||
|
||||
## Discord Chatroom
|
||||
|
||||
The Cosmopolitan development team collaborates on the Redbean Discord
|
||||
server. You're welcome to join us! <https://discord.gg/FwAVVu7eJ4>
|
||||
|
||||
## Support Vector
|
||||
|
||||
| Platform | Min Version | Circa |
|
||||
|
||||
@@ -116,11 +116,29 @@ cstr: .endobj cstr,globl,hidden # ←for gdb readability
|
||||
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.
|
||||
// WARNING: This prefix is experimental; it may be removed sometime.
|
||||
// TODO(jart): Find another prefix that will work with BIOS loading.
|
||||
.asciz "JTqFpD='\n" # Mark 'Zibo' Joseph Zbikowski
|
||||
.asciz "jartsr='\n" # Justine Alexandra Roberts Tunney
|
||||
// push $0x61
|
||||
// jb 0x78
|
||||
// jae 0x78
|
||||
#endif
|
||||
.short 0x1000 # MZ: lowers upper bound load / 16
|
||||
.short 0xf800 # MZ: roll greed on bss
|
||||
@@ -140,6 +158,9 @@ 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
|
||||
|
||||
@@ -261,6 +282,9 @@ 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)
|
||||
@@ -349,6 +373,7 @@ 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
|
||||
@@ -387,9 +412,6 @@ 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
|
||||
@@ -559,6 +581,9 @@ 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.
|
||||
@@ -660,17 +685,99 @@ apesh: .ascii "\n@\n#'\"\n" # sixth edition shebang
|
||||
.ascii "o=\"$t\"\n"
|
||||
.ascii "exec \"$o\" \"$@\"\n"
|
||||
#endif /* APE_NO_MODIFY_SELF */
|
||||
.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 "exit $?\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exit $R\n"
|
||||
|
||||
.ascii "PHDRS='' <<'@'\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-0.9.2\"\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"
|
||||
|
||||
.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
|
||||
@@ -1090,6 +1197,42 @@ 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
|
||||
@@ -1147,48 +1290,21 @@ sconf: .short 1843200/*hz*/ / 16/*wut*/ / 9600/*baud*/
|
||||
|
||||
// Global Descriptor Table
|
||||
.align 8
|
||||
_gdtrphy:
|
||||
.short 2f-1f-1 # table byte length
|
||||
.long REAL(1f) # table address (physical space)
|
||||
.endobj _gdtrphy,global,hidden
|
||||
_gdtrlo:
|
||||
.short 2f-_gdtlo-1 # table byte length
|
||||
.long REAL(_gdtlo) # table address (base memory space)
|
||||
.endobj _gdtrlo,global,hidden
|
||||
_gdtr:
|
||||
.short 2f-1f-1 # table byte length
|
||||
.quad 1f # table address (final virtual space)
|
||||
.short _gdt_end-_gdt-1 # table byte length
|
||||
.quad _gdt # table address (final virtual space)
|
||||
.endobj _gdtr,global,hidden
|
||||
.align 8
|
||||
_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
|
||||
// Partial GDT with descriptors for switching to unreal mode or long mode.
|
||||
_gdtlo = .-GDT_LEGACY_DATA
|
||||
.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 │
|
||||
@@ -1196,6 +1312,7 @@ _gdt:
|
||||
the default mode of operation on modern cpus */
|
||||
|
||||
realmodeloader:
|
||||
call lhinit
|
||||
call rlinit
|
||||
call sinit4
|
||||
.optfn _start16
|
||||
@@ -1203,6 +1320,25 @@ 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/*
|
||||
@@ -1263,17 +1399,19 @@ longmodeloader:
|
||||
call lcheck
|
||||
call a20
|
||||
call e820
|
||||
call cpyhi
|
||||
call loadhi
|
||||
call pinit
|
||||
call golong
|
||||
.endfn longmodeloader
|
||||
|
||||
// Long Mode Hardware Check
|
||||
lcheck: pushf # check for i8086 / i8088 / i80186
|
||||
pop %ax
|
||||
test $0x80,%ah # see intel manual volume 1 20.1.2
|
||||
jnz 10f # we now assume 32bit is supported
|
||||
pushfl # now check for i386 or early i486
|
||||
pop %eax # test ability to change cpuid bit
|
||||
lcheck: pushf # checks for i8086 / i8088 / i80186
|
||||
pop %ax # see intel manual volume 1 §20.1.2
|
||||
test $0x80,%ah
|
||||
jnz 10f # we now assume 32 bit is supported
|
||||
pushfl # now check for i386, or early i486
|
||||
pop %eax # tests ability to change cpuid bit
|
||||
mov %eax,%ecx
|
||||
mov $1<<21,%ebx
|
||||
xor %ebx,%eax
|
||||
@@ -1286,16 +1424,16 @@ lcheck: pushf # check for i8086 / i8088 / i80186
|
||||
or %ebx,%eax # puts cpuid bit in the on position
|
||||
push %eax
|
||||
popfl
|
||||
mov $0x80000000,%edi # get amd ext cpuid thingy length
|
||||
mov $0x80000000,%edi # get amd64 ext cpuid thingy length
|
||||
mov %edi,%eax
|
||||
inc %edi
|
||||
cpuid # clobbers eax, ebx, ecx, and edx
|
||||
cpuid # leaf 0x80000000, clob ax/bx/cx/dx
|
||||
cmp %edi,%eax
|
||||
jl 10f
|
||||
mov %edi,%eax
|
||||
cpuid
|
||||
mov $1<<29|1<<20,%edi # need nexgen32e long mode support
|
||||
and %edi,%edx # & nx support
|
||||
cpuid # leaf 0x80000001, clob ax/bx/cx/dx
|
||||
mov $1<<29|1<<20,%edi # 29 = LM (long), 20 = NX (no exec)
|
||||
and %edi,%edx # we need to both, or we won't work
|
||||
cmp %edi,%edx
|
||||
jne 10f
|
||||
xor %ax,%ax
|
||||
@@ -1405,10 +1543,88 @@ 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
|
||||
@@ -1449,7 +1665,7 @@ golong: cli
|
||||
rdmsr
|
||||
or $EFER_LME|EFER_SCE|EFER_NXE,%eax
|
||||
wrmsr
|
||||
lgdt REAL(_gdtrphy)
|
||||
lgdt REAL(_gdtrlo)
|
||||
mov %cr0,%eax
|
||||
or $CR0_PE|CR0_PG|CR0_MP,%eax
|
||||
and $~CR0_EM,%eax
|
||||
@@ -1459,7 +1675,9 @@ golong: cli
|
||||
|
||||
// Long mode is long.
|
||||
.code64
|
||||
long: xor %eax,%eax
|
||||
long: movabs $BANE+PHYSICAL(0f),%rax
|
||||
jmp *%rax
|
||||
0: xor %eax,%eax
|
||||
mov $GDT_LONG_DATA,%al
|
||||
mov %eax,%ds
|
||||
mov %eax,%ss
|
||||
@@ -1467,18 +1685,16 @@ long: xor %eax,%eax
|
||||
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_REAL,%edx
|
||||
mov $IMAGE_BASE_PHYSICAL,%edx
|
||||
lea v_ape_allbytes(%rdx),%ecx
|
||||
call __map_phdrs
|
||||
push $0x037f
|
||||
fldcw (%rsp)
|
||||
@@ -1564,6 +1780,10 @@ 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]
|
||||
@@ -1609,6 +1829,7 @@ 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
|
||||
@@ -1702,5 +1923,21 @@ __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
|
||||
|
||||
.end
|
||||
|
||||
+82
-32
@@ -216,6 +216,8 @@ SECTIONS {
|
||||
KEEP(*(.elf.phdrs))
|
||||
HIDDEN(ape_phdrs_end = .);
|
||||
|
||||
KEEP(*(.emush))
|
||||
|
||||
/* OpenBSD */
|
||||
. = ALIGN(__SIZEOF_POINTER__);
|
||||
HIDDEN(ape_note = .);
|
||||
@@ -273,6 +275,7 @@ SECTIONS {
|
||||
KEEP(*(.textwindowsprologue))
|
||||
*(.text.windows)
|
||||
KEEP(*(.textwindowsepilogue))
|
||||
KEEP(*(.blink))
|
||||
*(SORT_BY_ALIGNMENT(.text.modernity))
|
||||
*(SORT_BY_ALIGNMENT(.text.modernity.*))
|
||||
*(SORT_BY_ALIGNMENT(.text.hot))
|
||||
@@ -349,9 +352,30 @@ SECTIONS {
|
||||
HIDDEN(_etext = .);
|
||||
PROVIDE_HIDDEN(etext = .);
|
||||
/*END: Read Only Data (only needed for initialization) */
|
||||
/*END: Read Only Data */
|
||||
} :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
|
||||
|
||||
.data ALIGN(PAGESIZE) : {
|
||||
/*BEGIN: Read/Write Data */
|
||||
KEEP(*(SORT_BY_NAME(.piro.data.sort.iat.*)))
|
||||
@@ -385,26 +409,7 @@ 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 */
|
||||
|
||||
@@ -509,7 +514,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) + SIZEOF(.tdata));
|
||||
HIDDEN(ape_ram_filesz = SIZEOF(.data));
|
||||
HIDDEN(ape_ram_memsz = ADDR(.bss) + SIZEOF(.bss) - ape_ram_vaddr);
|
||||
HIDDEN(ape_ram_align = PAGESIZE);
|
||||
HIDDEN(ape_ram_rva = RVA(ape_ram_vaddr));
|
||||
@@ -533,16 +538,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));
|
||||
HIDDEN(ape_text_memsz = SIZEOF(.text));
|
||||
HIDDEN(ape_text_filesz = SIZEOF(.text) + SIZEOF(.tdata));
|
||||
HIDDEN(ape_text_memsz = SIZEOF(.text) + SIZEOF(.tdata));
|
||||
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) + SIZEOF(.tdata));
|
||||
HIDDEN(ape_data_memsz = SIZEOF(.data) + SIZEOF(.tdata));
|
||||
HIDDEN(ape_data_filesz = SIZEOF(.data));
|
||||
HIDDEN(ape_data_memsz = SIZEOF(.data));
|
||||
HIDDEN(ape_data_align = PAGESIZE);
|
||||
HIDDEN(ape_data_rva = RVA(ape_data_vaddr));
|
||||
|
||||
@@ -562,13 +567,58 @@ 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);
|
||||
|
||||
#if SupportsMetal()
|
||||
HIDDEN(v_ape_realsectors =
|
||||
MIN(0x70000 - IMAGE_BASE_REAL,
|
||||
ROUNDUP(RVA(_tdata_end), 512)) / 512);
|
||||
HIDDEN(v_ape_realpages = v_ape_realsectors / (4096 / 512));
|
||||
HIDDEN(v_ape_highsectors =
|
||||
(ROUNDUP(RVA(_tdata_end), 512) / 512) - 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 = MIN(0xffff, v_ape_allsectors - v_ape_realsectors));
|
||||
TSSDESCSTUB2(_tss, _tss, _tss_end ? _tss_end - _tss - 1 : 0);
|
||||
#endif
|
||||
|
||||
@@ -651,7 +701,7 @@ CHURN(ADDR(.bss));
|
||||
CHURN(_start);
|
||||
CHURN(ape_phdrs);
|
||||
#if SupportsMetal()
|
||||
CHURN(v_ape_realsectors);
|
||||
CHURN(v_ape_allsectors);
|
||||
#endif
|
||||
#if SupportsXnu()
|
||||
CHURN(ape_macho);
|
||||
@@ -715,7 +765,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");
|
||||
|
||||
+9
-1
@@ -96,6 +96,10 @@ o/ape/idata.inc: \
|
||||
ape/idata.internal.h \
|
||||
ape/relocations.h
|
||||
|
||||
o/$(MODE)/ape/ape.o: \
|
||||
ape/blink-aarch64.gz \
|
||||
ape/blink-darwin-arm64.gz
|
||||
|
||||
o/$(MODE)/ape/ape-no-modify-self.o: \
|
||||
ape/ape.S \
|
||||
ape/macros.internal.h \
|
||||
@@ -115,6 +119,8 @@ 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-darwin-arm64.gz \
|
||||
o/$(MODE)/ape/ape.elf
|
||||
@$(COMPILE) \
|
||||
-AOBJECTIFY.S \
|
||||
@@ -141,7 +147,9 @@ o/$(MODE)/ape/ape-copy-self.o: \
|
||||
libc/runtime/mman.internal.h \
|
||||
libc/runtime/pc.internal.h \
|
||||
libc/runtime/symbolic.h \
|
||||
libc/sysv/consts/prot.h
|
||||
libc/sysv/consts/prot.h \
|
||||
ape/blink-aarch64.gz \
|
||||
ape/blink-darwin-arm64.gz
|
||||
@$(COMPILE) \
|
||||
-AOBJECTIFY.S \
|
||||
$(OBJECTIFY.S) \
|
||||
|
||||
+2
-2
@@ -97,8 +97,8 @@ 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-sysv:M::JTqFpD::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
|
||||
$SUDO sh -c "echo ':APE-sysv:M::JTqFpD::/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
|
||||
|
||||
+8
-10
@@ -8,21 +8,19 @@ fi
|
||||
|
||||
{
|
||||
echo
|
||||
echo "APE Uninstaller intends to run"
|
||||
echo "APE Uninstaller intends to run (in pseudo-shell)"
|
||||
echo
|
||||
echo " $SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE'"
|
||||
echo " $SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE-sysv'"
|
||||
echo " $SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape /tmp/.ape"
|
||||
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
|
||||
echo "You may then use ape/apeinstall.sh to reinstall it"
|
||||
echo
|
||||
} >&2
|
||||
|
||||
set -ex
|
||||
if [ -f /proc/sys/fs/binfmt_misc/APE ]; then
|
||||
$SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE' || exit
|
||||
fi
|
||||
if [ -f /proc/sys/fs/binfmt_misc/APE-sysv ]; then
|
||||
$SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE-sysv' || exit
|
||||
fi
|
||||
for f in /proc/sys/fs/binfmt_misc/APE*; do
|
||||
if [ -f $f ]; then
|
||||
$SUDO sh -c "echo -1 >$f" || exit
|
||||
fi
|
||||
done
|
||||
$SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape o/tmp/ape /tmp/.ape /tmp/ape || exit
|
||||
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -45,7 +45,6 @@
|
||||
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
|
||||
|
||||
+4
-1
@@ -43,6 +43,9 @@
|
||||
# '(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' "$@"
|
||||
@@ -63,7 +66,7 @@ set -- --regex-c='/^extern [^(]*(\*const \([^)]*\))(/\1/b' "$@"
|
||||
# struct WorstSoftwareEver;
|
||||
set -- --regex-c='/^struct.*;$/uehocruehcroue/b' "$@"
|
||||
|
||||
exec ${TAGS:-ctags} \
|
||||
exec $TAGS \
|
||||
-e \
|
||||
--langmap=c:.c.h \
|
||||
--exclude=libc/nt/struct/imagefileheader.internal.h \
|
||||
|
||||
@@ -38,10 +38,12 @@ 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);
|
||||
|
||||
@@ -80,6 +80,7 @@ EXAMPLES_DIRECTDEPS = \
|
||||
THIRD_PARTY_LIBCXX \
|
||||
THIRD_PARTY_LINENOISE \
|
||||
THIRD_PARTY_LUA \
|
||||
THIRD_PARTY_HIREDIS \
|
||||
THIRD_PARTY_MBEDTLS \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_NSYNC \
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#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/stdio/stdio.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char buf[256];
|
||||
if (!getdomainname(buf, sizeof(buf))) {
|
||||
printf("%s\n", buf);
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#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;
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,43 @@
|
||||
#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)));
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -27,13 +27,13 @@ dontinline void ShowIt(const char *path) {
|
||||
"optimal transfer block size");
|
||||
sizefmt(ibuf, sf.f_frsize, 1024);
|
||||
printf("f_frsize = %,zu (%sb %s)\n", sf.f_frsize, ibuf, "fragment size");
|
||||
sizefmt(ibuf, sf.f_blocks * sf.f_bsize, 1024);
|
||||
sizefmt(ibuf, sf.f_blocks * sf.f_frsize, 1024);
|
||||
printf("f_blocks = %,zu (%sb %s)\n", sf.f_blocks, ibuf,
|
||||
"total data blocks in filesystem");
|
||||
sizefmt(ibuf, sf.f_bfree * sf.f_bsize, 1024);
|
||||
sizefmt(ibuf, sf.f_bfree * sf.f_frsize, 1024);
|
||||
printf("f_bfree = %,zu (%sb %s)\n", sf.f_bfree, ibuf,
|
||||
"free blocks in filesystem");
|
||||
sizefmt(ibuf, sf.f_bavail * sf.f_bsize, 1024);
|
||||
sizefmt(ibuf, sf.f_bavail * sf.f_frsize, 1024);
|
||||
printf("f_bavail = %,zu (%sb %s)\n", sf.f_bavail, ibuf,
|
||||
"free blocks available to use");
|
||||
printf("f_files = %,zu (%s)\n", sf.f_files,
|
||||
|
||||
+16
-16
@@ -46,31 +46,31 @@ int main(int argc, char *argv[]) {
|
||||
1. / 65536 * si.loads[1], //
|
||||
1. / 65536 * si.loads[2]); //
|
||||
|
||||
sizefmt(ibuf, si.totalram, 1024);
|
||||
printf("%-16s %s\n", "totalram", ibuf);
|
||||
sizefmt(ibuf, si.totalram * si.mem_unit, 1024);
|
||||
printf("%-16s %ld (%s)\n", "totalram", si.totalram, ibuf);
|
||||
|
||||
sizefmt(ibuf, si.freeram, 1024);
|
||||
printf("%-16s %s\n", "freeram", ibuf);
|
||||
sizefmt(ibuf, si.freeram * si.mem_unit, 1024);
|
||||
printf("%-16s %ld (%s)\n", "freeram", si.freeram, ibuf);
|
||||
|
||||
sizefmt(ibuf, si.sharedram, 1024);
|
||||
printf("%-16s %s\n", "sharedram", ibuf);
|
||||
sizefmt(ibuf, si.sharedram * si.mem_unit, 1024);
|
||||
printf("%-16s %ld (%s)\n", "sharedram", si.sharedram, ibuf);
|
||||
|
||||
sizefmt(ibuf, si.bufferram, 1024);
|
||||
printf("%-16s %s\n", "bufferram", ibuf);
|
||||
sizefmt(ibuf, si.bufferram * si.mem_unit, 1024);
|
||||
printf("%-16s %ld (%s)\n", "bufferram", si.bufferram, ibuf);
|
||||
|
||||
sizefmt(ibuf, si.totalswap, 1024);
|
||||
printf("%-16s %s\n", "totalswap", ibuf);
|
||||
sizefmt(ibuf, si.totalswap * si.mem_unit, 1024);
|
||||
printf("%-16s %ld (%s)\n", "totalswap", si.totalswap, ibuf);
|
||||
|
||||
sizefmt(ibuf, si.freeswap, 1024);
|
||||
printf("%-16s %s\n", "freeswap", ibuf);
|
||||
sizefmt(ibuf, si.freeswap * si.mem_unit, 1024);
|
||||
printf("%-16s %ld (%s)\n", "freeswap", si.freeswap, ibuf);
|
||||
|
||||
printf("%-16s %lu\n", "processes", si.procs);
|
||||
|
||||
sizefmt(ibuf, si.totalhigh, 1024);
|
||||
printf("%-16s %s\n", "totalhigh", ibuf);
|
||||
sizefmt(ibuf, si.totalhigh * si.mem_unit, 1024);
|
||||
printf("%-16s %ld (%s)\n", "totalhigh", si.totalhigh, ibuf);
|
||||
|
||||
sizefmt(ibuf, si.freehigh, 1024);
|
||||
printf("%-16s %s\n", "freehigh", ibuf);
|
||||
sizefmt(ibuf, si.freehigh * si.mem_unit, 1024);
|
||||
printf("%-16s %ld (%s)\n", "freehigh", si.freehigh, ibuf);
|
||||
|
||||
sizefmt(ibuf, si.mem_unit, 1024);
|
||||
printf("%-16s %s\n", "mem_unit", ibuf);
|
||||
|
||||
@@ -24,10 +24,16 @@
|
||||
|
||||
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 (;;);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#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_ */
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern bool __assert_disable;
|
||||
void __assert_fail(const char *, const char *, int) hidden relegated;
|
||||
void __assert_fail(const char *, const char *, int) _Hide relegated;
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define assert(x) ((void)0)
|
||||
|
||||
+23
-5
@@ -5,6 +5,25 @@
|
||||
#define _POSIX2_VERSION _POSIX_VERSION
|
||||
#define _XOPEN_VERSION 700
|
||||
|
||||
#define _POSIX_MAPPED_FILES _POSIX_VERSION
|
||||
#define _POSIX_FSYNC _POSIX_VERSION
|
||||
#define _POSIX_IPV6 _POSIX_VERSION
|
||||
#define _POSIX_THREADS _POSIX_VERSION
|
||||
#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
|
||||
#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
|
||||
#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION
|
||||
#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION
|
||||
#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION
|
||||
#define _POSIX_THREAD_CPUTIME _POSIX_VERSION
|
||||
#define _POSIX_TIMEOUTS _POSIX_VERSION
|
||||
#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION
|
||||
#define _POSIX_CPUTIME _POSIX_VERSION
|
||||
#define _POSIX_BARRIERS _POSIX_VERSION
|
||||
#define _POSIX_SPIN_LOCKS _POSIX_VERSION
|
||||
#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION
|
||||
#define _POSIX_SEMAPHORES _POSIX_VERSION
|
||||
#define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_VERSION
|
||||
|
||||
#define EOF -1 /* end of file */
|
||||
#define WEOF -1u /* end of file (multibyte) */
|
||||
#define _IOFBF 0 /* fully buffered */
|
||||
@@ -35,11 +54,10 @@
|
||||
#define WIFCONTINUED(s) ((s) == 0xffff)
|
||||
#define WIFEXITED(s) (!WTERMSIG(s))
|
||||
#define WIFSIGNALED(s) ((0xffff & (s)) - 1u < 0xffu)
|
||||
#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)
|
||||
#define WIFSTOPPED(s) ((255 & (s)) == 127)
|
||||
#define WSTOPSIG(s) WEXITSTATUS(s)
|
||||
#define WTERMSIG(s) (127 & (s))
|
||||
#define W_STOPCODE(s) ((s) << 8 | 0177)
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
+1
-10
@@ -121,21 +121,12 @@ 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 \
|
||||
|
||||
+18
-15
@@ -50,20 +50,23 @@
|
||||
* 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_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
|
||||
* - `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
|
||||
* @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
|
||||
@@ -116,7 +119,7 @@ clock_gettime_f *__clock_gettime_get(bool *opt_out_isfast) {
|
||||
return res;
|
||||
}
|
||||
|
||||
hidden int __clock_gettime_init(int clockid, struct timespec *ts) {
|
||||
_Hide 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 *) hidden;
|
||||
int __clock_gettime_init(int, struct timespec *) hidden;
|
||||
int sys_clock_gettime_mono(struct timespec *) hidden;
|
||||
clock_gettime_f *__clock_gettime_get(bool *) _Hide;
|
||||
int __clock_gettime_init(int, struct timespec *) _Hide;
|
||||
int sys_clock_gettime_mono(struct timespec *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
+165
-27
@@ -16,7 +16,11 @@
|
||||
│ 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"
|
||||
@@ -27,11 +31,158 @@
|
||||
#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.
|
||||
*
|
||||
@@ -61,7 +212,7 @@
|
||||
* while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &abs, 0));
|
||||
*
|
||||
* will accurately spin on `EINTR` errors. That way you're not impeding
|
||||
* signal delivery and you're not losing precision on your wait timeout.
|
||||
* signal delivery and you're not loosing precision on the wait timeout.
|
||||
* This function has first-class support on Linux, FreeBSD, and NetBSD;
|
||||
* on OpenBSD it's good; on XNU it's bad; and on Windows it's ugly.
|
||||
*
|
||||
@@ -88,43 +239,30 @@
|
||||
*/
|
||||
errno_t clock_nanosleep(int clock, int flags, const struct timespec *req,
|
||||
struct timespec *rem) {
|
||||
int rc, e = errno;
|
||||
BEGIN_CANCELLATION_POINT;
|
||||
|
||||
if (!req || (IsAsan() && (!__asan_is_valid_timespec(req) ||
|
||||
(rem && !__asan_is_valid_timespec(rem))))) {
|
||||
rc = efault();
|
||||
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;
|
||||
} else if (clock == 127 || //
|
||||
(flags & ~TIMER_ABSTIME) || //
|
||||
req->tv_sec < 0 || //
|
||||
!(0 <= req->tv_nsec && req->tv_nsec <= 999999999)) {
|
||||
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();
|
||||
rc = EINVAL;
|
||||
} else if (ShouldUseSpinNanosleep(clock, flags, req)) {
|
||||
rc = SpinNanosleep(clock, flags, req, rem);
|
||||
} else {
|
||||
rc = sys_clock_nanosleep_nt(clock, flags, req, rem);
|
||||
rc = sys_clock_nanosleep(clock, flags, req, rem);
|
||||
}
|
||||
|
||||
if (rc == -1) {
|
||||
rc = errno;
|
||||
errno = e;
|
||||
}
|
||||
|
||||
END_CANCELLATION_POINT;
|
||||
|
||||
#if SYSDEBUG
|
||||
if (__tls_enabled && !(__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), DescribeErrnoResult(rc));
|
||||
DescribeTimespec(rc, rem), DescribeErrno(rc));
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
||||
void sys_fcntl_nt_lock_cleanup(int) hidden;
|
||||
void sys_fcntl_nt_lock_cleanup(int) _Hide;
|
||||
|
||||
textwindows int sys_close_nt(struct Fd *fd, int fildes) {
|
||||
int e;
|
||||
|
||||
+18
-4
@@ -16,16 +16,18 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/ok.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static bool IsExePath(const char *s, size_t n) {
|
||||
@@ -48,6 +50,9 @@ static bool AccessCommand(const char *name, char *path, size_t pathsz,
|
||||
size_t pathlen) {
|
||||
size_t suffixlen;
|
||||
suffixlen = strlen(suffix);
|
||||
if (IsWindows() && suffixlen == 0 && !IsExePath(name, namelen) &&
|
||||
!IsComPath(name, namelen))
|
||||
return false;
|
||||
if (pathlen + 1 + namelen + suffixlen + 1 > pathsz) return false;
|
||||
if (pathlen && (path[pathlen - 1] != '/' && path[pathlen - 1] != '\\')) {
|
||||
path[pathlen] = !IsWindows() ? '/'
|
||||
@@ -57,7 +62,16 @@ static bool AccessCommand(const char *name, char *path, size_t pathsz,
|
||||
}
|
||||
memcpy(path + pathlen, name, namelen);
|
||||
memcpy(path + pathlen + namelen, suffix, suffixlen + 1);
|
||||
if (!access(path, X_OK)) return true;
|
||||
if (!access(path, X_OK)) {
|
||||
struct stat st;
|
||||
if (!stat(path, &st)) {
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
return true;
|
||||
} else {
|
||||
errno = EACCES;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errno == EACCES || *err != EACCES) *err = errno;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/blocksigs.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/execve-sysv.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
@@ -37,6 +38,11 @@ static bool CanExecute(const char *path) {
|
||||
return !sys_faccessat(AT_FDCWD, path, X_OK, 0);
|
||||
}
|
||||
|
||||
bool IsAPEMagic(char buf[8]) {
|
||||
return READ64LE(buf) == READ64LE("MZqFpD='") ||
|
||||
READ64LE(buf) == READ64LE("JTqFpD='");
|
||||
}
|
||||
|
||||
static bool IsApeBinary(const char *path) {
|
||||
int fd;
|
||||
char buf[8];
|
||||
@@ -44,11 +50,7 @@ static bool IsApeBinary(const char *path) {
|
||||
// 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='"))) {
|
||||
res = true;
|
||||
}
|
||||
res = sys_read(fd, buf, 8) == 8 && IsAPEMagic(buf);
|
||||
sys_close(fd);
|
||||
}
|
||||
ALLOW_CANCELLATIONS;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_EXECVE_SYSV_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_EXECVE_SYSV_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
bool IsAPEMagic(char[8]) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_EXECVE_SYSV_H_ */
|
||||
+20
-8
@@ -32,6 +32,7 @@
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Replaces current process with program.
|
||||
@@ -51,6 +52,7 @@
|
||||
* @vforksafe
|
||||
*/
|
||||
int execve(const char *prog, char *const argv[], char *const envp[]) {
|
||||
struct ZiposUri uri;
|
||||
int rc;
|
||||
size_t i;
|
||||
if (!prog || !argv || !envp ||
|
||||
@@ -61,16 +63,26 @@ int execve(const char *prog, char *const argv[], char *const envp[]) {
|
||||
} else {
|
||||
STRACE("execve(%#s, %s, %s) → ...", prog, DescribeStringList(argv),
|
||||
DescribeStringList(envp));
|
||||
if (!IsWindows()) {
|
||||
rc = 0;
|
||||
if (IsLinux() && __execpromises && _weaken(sys_pledge_linux)) {
|
||||
rc = _weaken(sys_pledge_linux)(__execpromises, __pledge_mode);
|
||||
}
|
||||
if (!rc) {
|
||||
rc = 0;
|
||||
if (IsLinux() && __execpromises && _weaken(sys_pledge_linux)) {
|
||||
rc = _weaken(sys_pledge_linux)(__execpromises, __pledge_mode);
|
||||
}
|
||||
if (!rc) {
|
||||
if (_weaken(__zipos_parseuri) &&
|
||||
(_weaken(__zipos_parseuri)(prog, &uri) != -1)) {
|
||||
rc = _weaken(__zipos_open)(&uri, O_RDONLY | O_CLOEXEC, 0);
|
||||
if (rc != -1) {
|
||||
const int zipFD = rc;
|
||||
strace_enabled(-1);
|
||||
rc = fexecve(zipFD, argv, envp);
|
||||
close(zipFD);
|
||||
strace_enabled(+1);
|
||||
}
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_execve(prog, argv, envp);
|
||||
} else {
|
||||
rc = sys_execve_nt(prog, argv, envp);
|
||||
}
|
||||
} else {
|
||||
rc = sys_execve_nt(prog, argv, envp);
|
||||
}
|
||||
}
|
||||
STRACE("execve(%#s) failed %d% m", prog, rc);
|
||||
|
||||
@@ -98,7 +98,7 @@ static textwindows bool EqualsFileLock(struct FileLock *fl, int64_t off,
|
||||
return fl->off == off && off + len == fl->off + fl->len;
|
||||
}
|
||||
|
||||
hidden textwindows void sys_fcntl_nt_lock_cleanup(int fd) {
|
||||
_Hide textwindows void sys_fcntl_nt_lock_cleanup(int fd) {
|
||||
struct FileLock *fl, *ft, **flp;
|
||||
pthread_mutex_lock(&g_locks.mu);
|
||||
for (flp = &g_locks.list, fl = *flp; fl;) {
|
||||
|
||||
+208
-13
@@ -16,23 +16,167 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/blocksigs.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/cp.internal.h"
|
||||
#include "libc/calls/execve-sysv.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/stat.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/f.h"
|
||||
#include "libc/sysv/consts/fd.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/mfd.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/sysv/consts/shm.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int sys_fexecve(int, char *const[], char *const[]);
|
||||
static bool IsAPEFd(const int fd) {
|
||||
char buf[8];
|
||||
bool res;
|
||||
return (sys_pread(fd, buf, 8, 0, 0) == 8) && IsAPEMagic(buf);
|
||||
}
|
||||
|
||||
static int fexecve_impl(const int fd, char *const argv[], char *const envp[]) {
|
||||
int rc;
|
||||
if (IsLinux()) {
|
||||
char path[14 + 12];
|
||||
FormatInt32(stpcpy(path, "/proc/self/fd/"), fd);
|
||||
rc = __sys_execve(path, argv, envp);
|
||||
} else if (IsFreebsd()) {
|
||||
rc = sys_fexecve(fd, argv, envp);
|
||||
} else {
|
||||
rc = enosys();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
PTF_NUM = 1 << 0,
|
||||
PTF_NUM2 = 1 << 1,
|
||||
PTF_NUM3 = 1 << 2,
|
||||
PTF_ANY = 1 << 3
|
||||
} PTF_PARSE;
|
||||
|
||||
static bool ape_to_elf(void *ape, const size_t apesize) {
|
||||
static const char printftok[] = "printf '";
|
||||
static const size_t printftoklen = sizeof(printftok) - 1;
|
||||
const char *tok = memmem(ape, apesize, printftok, printftoklen);
|
||||
if (tok) {
|
||||
tok += printftoklen;
|
||||
uint8_t *dest = ape;
|
||||
PTF_PARSE state = PTF_ANY;
|
||||
uint8_t value = 0;
|
||||
for (; tok < (const char *)(dest + apesize); tok++) {
|
||||
if ((state & (PTF_NUM | PTF_NUM2 | PTF_NUM3)) &&
|
||||
(*tok >= '0' && *tok <= '7')) {
|
||||
value = (value << 3) | (*tok - '0');
|
||||
state <<= 1;
|
||||
if (state & PTF_ANY) {
|
||||
*dest++ = value;
|
||||
}
|
||||
} else if (state & PTF_NUM) {
|
||||
break;
|
||||
} else {
|
||||
if (state & (PTF_NUM2 | PTF_NUM3)) {
|
||||
*dest++ = value;
|
||||
}
|
||||
if (*tok == '\\') {
|
||||
state = PTF_NUM;
|
||||
value = 0;
|
||||
} else if (*tok == '\'') {
|
||||
return true;
|
||||
} else {
|
||||
*dest++ = *tok;
|
||||
state = PTF_ANY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
errno = ENOEXEC;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a memfd and copies fd to it.
|
||||
*
|
||||
* This does an inplace conversion of APE to ELF when detected!!!!
|
||||
*/
|
||||
static int fd_to_mem_fd(const int infd, char *path) {
|
||||
if (!IsLinux() && !IsFreebsd() || !_weaken(mmap) || !_weaken(munmap)) {
|
||||
return enosys();
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
if (fstat(infd, &st) == -1) {
|
||||
return -1;
|
||||
}
|
||||
int fd;
|
||||
if (IsLinux()) {
|
||||
fd = sys_memfd_create(__func__, MFD_CLOEXEC);
|
||||
} else if (IsFreebsd()) {
|
||||
fd = sys_shm_open(SHM_ANON, O_CREAT | O_RDWR, 0);
|
||||
} else {
|
||||
return enosys();
|
||||
}
|
||||
if (fd == -1) {
|
||||
return -1;
|
||||
}
|
||||
void *space;
|
||||
if ((sys_ftruncate(fd, st.st_size, st.st_size) != -1) &&
|
||||
((space = _weaken(mmap)(0, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
fd, 0)) != MAP_FAILED)) {
|
||||
ssize_t readRc;
|
||||
readRc = pread(infd, space, st.st_size, 0);
|
||||
bool success = readRc != -1;
|
||||
if (success && (st.st_size > 8) && IsAPEMagic(space)) {
|
||||
int flags = fcntl(fd, F_GETFD);
|
||||
if (success = (flags != -1) &&
|
||||
(fcntl(fd, F_SETFD, flags & (~FD_CLOEXEC)) != -1) &&
|
||||
ape_to_elf(space, st.st_size)) {
|
||||
const int newfd = fcntl(fd, F_DUPFD, 9001);
|
||||
if (newfd != -1) {
|
||||
close(fd);
|
||||
fd = newfd;
|
||||
}
|
||||
}
|
||||
}
|
||||
const int e = errno;
|
||||
if ((_weaken(munmap)(space, st.st_size) != -1) && success) {
|
||||
if (path) {
|
||||
FormatInt32(stpcpy(path, "COSMOPOLITAN_INIT_ZIPOS="), fd);
|
||||
}
|
||||
_unassert(readRc == st.st_size);
|
||||
return fd;
|
||||
} else if (!success) {
|
||||
errno = e;
|
||||
}
|
||||
}
|
||||
const int e = errno;
|
||||
close(fd);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes binary executable at file descriptor.
|
||||
*
|
||||
* This is only supported on Linux and FreeBSD. APE binaries currently
|
||||
* aren't supported.
|
||||
* This is only supported on Linux and FreeBSD. APE binaries are
|
||||
* supported. Zipos is supported. Zipos fds or FD_CLOEXEC APE fds or
|
||||
* fds that fail fexecve with ENOEXEC are copied to a new memfd (with
|
||||
* in-memory APE to ELF conversion) and fexecve is (re)attempted.
|
||||
*
|
||||
* @param fd is opened executable and current file position is ignored
|
||||
* @return doesn't return on success, otherwise -1 w/ errno
|
||||
@@ -40,8 +184,7 @@ int sys_fexecve(int, char *const[], char *const[]);
|
||||
* @raise ENOSYS on Windows, XNU, OpenBSD, NetBSD, and Metal
|
||||
*/
|
||||
int fexecve(int fd, char *const argv[], char *const envp[]) {
|
||||
int rc;
|
||||
size_t i;
|
||||
int rc = 0;
|
||||
if (!argv || !envp ||
|
||||
(IsAsan() &&
|
||||
(!__asan_is_valid_strlist(argv) || !__asan_is_valid_strlist(envp)))) {
|
||||
@@ -49,15 +192,67 @@ int fexecve(int fd, char *const argv[], char *const envp[]) {
|
||||
} else {
|
||||
STRACE("fexecve(%d, %s, %s) → ...", fd, DescribeStringList(argv),
|
||||
DescribeStringList(envp));
|
||||
if (IsLinux()) {
|
||||
char path[14 + 12];
|
||||
FormatInt32(stpcpy(path, "/proc/self/fd/"), fd);
|
||||
rc = __sys_execve(path, argv, envp);
|
||||
} else if (IsFreebsd()) {
|
||||
rc = sys_fexecve(fd, argv, envp);
|
||||
} else {
|
||||
rc = enosys();
|
||||
int savedErr = 0;
|
||||
do {
|
||||
if (!IsLinux() && !IsFreebsd()) {
|
||||
rc = enosys();
|
||||
break;
|
||||
}
|
||||
if (!__isfdkind(fd, kFdZip)) {
|
||||
bool memfdReq;
|
||||
BEGIN_CANCELLATION_POINT;
|
||||
BLOCK_SIGNALS;
|
||||
strace_enabled(-1);
|
||||
memfdReq = ((rc = fcntl(fd, F_GETFD)) != -1) && (rc & FD_CLOEXEC) &&
|
||||
IsAPEFd(fd);
|
||||
strace_enabled(+1);
|
||||
ALLOW_SIGNALS;
|
||||
END_CANCELLATION_POINT;
|
||||
if (rc == -1) {
|
||||
break;
|
||||
} else if (!memfdReq) {
|
||||
fexecve_impl(fd, argv, envp);
|
||||
if (errno != ENOEXEC) {
|
||||
break;
|
||||
}
|
||||
savedErr = ENOEXEC;
|
||||
}
|
||||
}
|
||||
int newfd;
|
||||
char *path = alloca(PATH_MAX);
|
||||
BEGIN_CANCELLATION_POINT;
|
||||
BLOCK_SIGNALS;
|
||||
strace_enabled(-1);
|
||||
newfd = fd_to_mem_fd(fd, path);
|
||||
strace_enabled(+1);
|
||||
ALLOW_SIGNALS;
|
||||
END_CANCELLATION_POINT;
|
||||
if (newfd == -1) {
|
||||
break;
|
||||
}
|
||||
size_t numenvs;
|
||||
for (numenvs = 0; envp[numenvs];) ++numenvs;
|
||||
const size_t desenvs = min(500, max(numenvs + 1, 2));
|
||||
static _Thread_local char *envs[500];
|
||||
memcpy(envs, envp, numenvs * sizeof(char *));
|
||||
envs[numenvs] = path;
|
||||
envs[numenvs + 1] = NULL;
|
||||
fexecve_impl(newfd, argv, envs);
|
||||
if (!savedErr) {
|
||||
savedErr = errno;
|
||||
}
|
||||
BEGIN_CANCELLATION_POINT;
|
||||
BLOCK_SIGNALS;
|
||||
strace_enabled(-1);
|
||||
close(newfd);
|
||||
strace_enabled(+1);
|
||||
ALLOW_SIGNALS;
|
||||
END_CANCELLATION_POINT;
|
||||
} while (0);
|
||||
if (savedErr) {
|
||||
errno = savedErr;
|
||||
}
|
||||
rc = -1;
|
||||
}
|
||||
STRACE("fexecve(%d) failed %d% m", fd, rc);
|
||||
return rc;
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ int fsync(int fd) {
|
||||
rc = sys_fdatasync_nt(fd);
|
||||
}
|
||||
END_CANCELLATION_POINT;
|
||||
STRACE("fysnc(%d) → %d% m", fd, rc);
|
||||
STRACE("fsync(%d) → %d% m", fd, rc);
|
||||
} else {
|
||||
rc = fstat(fd, &st);
|
||||
STRACE("fsync_fake(%d) → %d% m", fd, rc);
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_
|
||||
#include "libc/nt/enum/ctrlevent.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
static inline int GetConsoleCtrlEvent(int sig) {
|
||||
switch (sig) {
|
||||
case SIGINT:
|
||||
return kNtCtrlCEvent;
|
||||
case SIGQUIT:
|
||||
return kNtCtrlBreakEvent;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_ */
|
||||
@@ -17,12 +17,14 @@
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
|
||||
/**
|
||||
* Returns process group id of calling process.
|
||||
*
|
||||
* This function is equivalent to `getpgid(0)`.
|
||||
*/
|
||||
int getpgrp(void) {
|
||||
int rc;
|
||||
|
||||
@@ -97,7 +97,7 @@ gettimeofday_f *__gettimeofday_get(bool *opt_out_isfast) {
|
||||
return res;
|
||||
}
|
||||
|
||||
hidden int __gettimeofday_init(struct timeval *tv, struct timezone *tz) {
|
||||
_Hide int __gettimeofday_init(struct timeval *tv, struct timezone *tz) {
|
||||
gettimeofday_f *gettime;
|
||||
__gettimeofday = gettime = __gettimeofday_get(0);
|
||||
return gettime(tv, tz, 0).ax;
|
||||
|
||||
+10
-10
@@ -12,15 +12,15 @@ COSMOPOLITAN_C_START_
|
||||
|
||||
#define kIoMotion ((const int8_t[3]){1, 0, 0})
|
||||
|
||||
hidden extern struct Fds g_fds;
|
||||
hidden extern const struct Fd kEmptyFd;
|
||||
_Hide extern struct Fds g_fds;
|
||||
_Hide extern const struct Fd kEmptyFd;
|
||||
|
||||
int __reservefd(int) hidden;
|
||||
int __reservefd_unlocked(int) hidden;
|
||||
void __releasefd(int) hidden;
|
||||
int __ensurefds(int) hidden;
|
||||
int __ensurefds_unlocked(int) hidden;
|
||||
void __printfds(void) hidden;
|
||||
int __reservefd(int) _Hide;
|
||||
int __reservefd_unlocked(int) _Hide;
|
||||
void __releasefd(int) _Hide;
|
||||
int __ensurefds(int) _Hide;
|
||||
int __ensurefds_unlocked(int) _Hide;
|
||||
void __printfds(void) _Hide;
|
||||
|
||||
forceinline int64_t __getfdhandleactual(int fd) {
|
||||
return g_fds.p[fd].handle;
|
||||
@@ -42,8 +42,8 @@ forceinline size_t _clampio(size_t size) {
|
||||
}
|
||||
}
|
||||
|
||||
int sys_close_nt(struct Fd *, int) hidden;
|
||||
int _check_interrupts(bool, struct Fd *) hidden;
|
||||
int sys_close_nt(struct Fd *, int) _Hide;
|
||||
int _check_interrupts(bool, struct Fd *) _Hide;
|
||||
int sys_openat_metal(int, const char *, int, unsigned);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
|
||||
@@ -43,11 +43,11 @@
|
||||
* The ifc_len is an input/output parameter: set it to the total size of
|
||||
* the ifcu_buf (ifcu_req) buffer on input.
|
||||
*/
|
||||
int ioctl_siocgifconf_nt(int, struct ifconf *) hidden;
|
||||
int ioctl_siocgifaddr_nt(int, struct ifreq *) hidden;
|
||||
int ioctl_siocgifflags_nt(int, struct ifreq *) hidden;
|
||||
int ioctl_siocgifnetmask_nt(int, struct ifreq *) hidden;
|
||||
int ioctl_siocgifbrdaddr_nt(int, struct ifreq *) hidden;
|
||||
int ioctl_siocgifconf_nt(int, struct ifconf *) _Hide;
|
||||
int ioctl_siocgifaddr_nt(int, struct ifreq *) _Hide;
|
||||
int ioctl_siocgifflags_nt(int, struct ifreq *) _Hide;
|
||||
int ioctl_siocgifnetmask_nt(int, struct ifreq *) _Hide;
|
||||
int ioctl_siocgifbrdaddr_nt(int, struct ifreq *) _Hide;
|
||||
|
||||
static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
|
||||
/*
|
||||
|
||||
@@ -18,18 +18,18 @@
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/struct/metatermios.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/calls/termios.internal.h"
|
||||
#include "libc/calls/ttydefaults.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int ioctl_tcgets_nt(int, struct termios *) hidden;
|
||||
int ioctl_tcgets_nt(int, struct termios *) _Hide;
|
||||
|
||||
static int ioctl_tcgets_metal(int fd, struct termios *tio) {
|
||||
bzero(tio, sizeof(*tio));
|
||||
|
||||
@@ -18,11 +18,13 @@
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/pr.h"
|
||||
|
||||
privileged bool __is_linux_2_6_23(void) {
|
||||
int rc;
|
||||
if (!IsLinux()) return false;
|
||||
if (IsGenuineBlink()) return true;
|
||||
asm volatile("syscall"
|
||||
: "=a"(rc)
|
||||
: "0"(157), "D"(PR_GET_SECCOMP)
|
||||
|
||||
@@ -19,4 +19,4 @@
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
|
||||
hidden const struct Fd kEmptyFd;
|
||||
_Hide const struct Fd kEmptyFd;
|
||||
+19
-4
@@ -17,7 +17,6 @@
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/getconsolectrlevent.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.internal.h"
|
||||
@@ -29,8 +28,20 @@
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/processentry32.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static inline int GetConsoleCtrlEvent(int sig) {
|
||||
switch (sig) {
|
||||
case SIGINT:
|
||||
return kNtCtrlCEvent;
|
||||
case SIGQUIT:
|
||||
return kNtCtrlBreakEvent;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
textwindows int sys_kill_nt(int pid, int sig) {
|
||||
bool32 ok;
|
||||
int64_t h;
|
||||
@@ -46,6 +57,7 @@ textwindows int sys_kill_nt(int pid, int sig) {
|
||||
|
||||
// If we're targeting current process group then just call raise().
|
||||
if (!pid || pid == getpid()) {
|
||||
if (!sig) return 0; // ability check passes
|
||||
return raise(sig);
|
||||
}
|
||||
|
||||
@@ -72,6 +84,7 @@ textwindows int sys_kill_nt(int pid, int sig) {
|
||||
|
||||
// is this a cosmo pid that was returned by fork?
|
||||
if (__isfdkind(pid, kFdProcess)) {
|
||||
if (!sig) return 0; // ability check passes
|
||||
// since windows can't execve we need to kill the grandchildren
|
||||
// TODO(jart): should we just kill the whole tree too? there's
|
||||
// no obvious way to tell if it's the execve shell
|
||||
@@ -96,9 +109,11 @@ textwindows int sys_kill_nt(int pid, int sig) {
|
||||
|
||||
// XXX: Is this a raw new technology pid? Because that's messy.
|
||||
if ((h = OpenProcess(kNtProcessTerminate, false, pid))) {
|
||||
ok = TerminateProcess(h, 128 + sig);
|
||||
if (!ok && GetLastError() == kNtErrorAccessDenied) {
|
||||
ok = true; // cargo culting other codebases here
|
||||
if (sig) {
|
||||
ok = TerminateProcess(h, 128 + sig);
|
||||
if (!ok && GetLastError() == kNtErrorAccessDenied) {
|
||||
ok = true; // cargo culting other codebases here
|
||||
}
|
||||
}
|
||||
CloseHandle(h);
|
||||
return 0;
|
||||
|
||||
@@ -26,6 +26,15 @@
|
||||
*/
|
||||
#define LANDLOCK_ACCESS_FS_REFER 0x2000ul
|
||||
|
||||
/**
|
||||
* Control file truncation.
|
||||
*
|
||||
* @see https://lore.kernel.org/all/[email protected]/
|
||||
* @see https://docs.kernel.org/userspace-api/landlock.html
|
||||
* @note ABI 3+
|
||||
*/
|
||||
#define LANDLOCK_ACCESS_FS_TRUNCATE 0x4000ul
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
|
||||
@@ -61,14 +61,14 @@ textstartup noasan void InitializeMetalFile(void) {
|
||||
* The zipos code will automatically arrange to do this. Alternatively,
|
||||
* user code can STATIC_YOINK this symbol.
|
||||
*/
|
||||
size_t size = ROUNDUP(_tdata_end - _base, 4096);
|
||||
size_t size = ROUNDUP(_ezip - _base, 4096);
|
||||
void *copied_base;
|
||||
struct DirectMap dm;
|
||||
dm = sys_mmap_metal(NULL, size, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED_linux | MAP_ANONYMOUS_linux, -1, 0);
|
||||
copied_base = dm.addr;
|
||||
_npassert(copied_base != (void *)-1);
|
||||
memcpy(copied_base, (void *)(BANE + IMAGE_BASE_REAL), size);
|
||||
memcpy(copied_base, (void *)(BANE + IMAGE_BASE_PHYSICAL), size);
|
||||
__ape_com_base = copied_base;
|
||||
__ape_com_size = size;
|
||||
}
|
||||
|
||||
@@ -61,15 +61,12 @@ static inline int IsAlpha(int c) {
|
||||
// TODO(jart): this needs fuzzing and security review
|
||||
//
|
||||
// @param cmdline is output buffer
|
||||
// @param prog is frontloaded as argv[0]
|
||||
// @param argv is an a NULL-terminated array of UTF-8 strings
|
||||
// @return 0 on success, or -1 w/ errno
|
||||
// @raise E2BIG if everything is too huge
|
||||
// @see "Everyone quotes command line arguments the wrong way" MSDN
|
||||
// @see libc/runtime/getdosargv.c
|
||||
textwindows int mkntcmdline(char16_t cmdline[ARG_MAX / 2], const char *prog,
|
||||
char *const argv[]) {
|
||||
char *arg;
|
||||
textwindows int mkntcmdline(char16_t cmdline[ARG_MAX / 2], char *const argv[]) {
|
||||
uint64_t w;
|
||||
wint_t x, y;
|
||||
int slashes, n;
|
||||
@@ -81,16 +78,16 @@ textwindows int mkntcmdline(char16_t cmdline[ARG_MAX / 2], const char *prog,
|
||||
bzero(ansiargv, sizeof(ansiargv));
|
||||
argv = ansiargv;
|
||||
}
|
||||
for (arg = prog, k = i = 0; arg; arg = argv[++i]) {
|
||||
for (k = i = 0; argv[i]; ++i) {
|
||||
if (i) APPEND(u' ');
|
||||
if ((needsquote = NeedsQuotes(arg))) APPEND(u'"');
|
||||
if ((needsquote = NeedsQuotes(argv[i]))) APPEND(u'"');
|
||||
for (slashes = j = 0;;) {
|
||||
x = arg[j++] & 255;
|
||||
x = argv[i][j++] & 255;
|
||||
if (x >= 0300) {
|
||||
n = ThomPikeLen(x);
|
||||
x = ThomPikeByte(x);
|
||||
while (--n) {
|
||||
if ((y = arg[j++] & 255)) {
|
||||
if ((y = argv[i][j++] & 255)) {
|
||||
x = ThomPikeMerge(x, y);
|
||||
} else {
|
||||
x = 0;
|
||||
@@ -101,9 +98,9 @@ textwindows int mkntcmdline(char16_t cmdline[ARG_MAX / 2], const char *prog,
|
||||
if (!x) break;
|
||||
if (x == '/' || x == '\\') {
|
||||
if (!i) {
|
||||
// turn / into \ for first arg
|
||||
// turn / into \ for first argv[i]
|
||||
x = '\\';
|
||||
// turn \c\... into c:\ for first arg
|
||||
// turn \c\... into c:\ for first argv[i]
|
||||
if (k == 2 && IsAlpha(cmdline[1]) && cmdline[0] == '\\') {
|
||||
cmdline[0] = cmdline[1];
|
||||
cmdline[1] = ':';
|
||||
|
||||
@@ -79,7 +79,7 @@ textwindows int __mkntpath2(const char *path,
|
||||
* 1. Need +1 for NUL-terminator
|
||||
* 2. Need +1 for UTF-16 overflow
|
||||
* 3. Need ≥2 for SetCurrentDirectory trailing slash requirement
|
||||
* 5. Need ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
|
||||
* 4. Need ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
|
||||
* which is an "8.3 filename" from the DOS days
|
||||
*/
|
||||
const char *q;
|
||||
@@ -119,7 +119,7 @@ textwindows int __mkntpath2(const char *path,
|
||||
q += 2;
|
||||
z -= 7;
|
||||
x = 7;
|
||||
} else if (IsSlash(q[0]) && IsAlpha(q[1]) && IsSlash(q[2])) {
|
||||
} else if (IsAlpha(q[0]) && q[1] == ':' && IsSlash(q[2])) {
|
||||
z = MIN(32767, PATH_MAX);
|
||||
// turn "c:\foo" into "\\?\c:\foo"
|
||||
p[0] = '\\';
|
||||
|
||||
@@ -21,13 +21,18 @@
|
||||
|
||||
noasan int sys_munmap_metal(void *addr, size_t size) {
|
||||
size_t i;
|
||||
uint64_t *e;
|
||||
uint64_t *e, paddr;
|
||||
struct mman *mm;
|
||||
uint64_t *pml4t = __get_pml4t();
|
||||
mm = (struct mman *)(BANE + 0x0500);
|
||||
for (i = 0; i < size; i += 4096) {
|
||||
e = __get_virtual(mm, __get_pml4t(), (uint64_t)addr + i, false);
|
||||
if (e) *e = ~(PAGE_V | PAGE_RSRV);
|
||||
invlpg((uint64_t)addr + i);
|
||||
e = __get_virtual(mm, pml4t, (uint64_t)addr + i, false);
|
||||
if (e) {
|
||||
paddr = *e & PAGE_TA;
|
||||
*e &= ~(PAGE_V | PAGE_RSRV);
|
||||
invlpg((uint64_t)addr + i);
|
||||
__unref_page(mm, pml4t, paddr);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+5
-5
@@ -45,10 +45,10 @@ static long double GetTimeSample(void) {
|
||||
uint64_t tick1, tick2;
|
||||
long double time1, time2;
|
||||
sched_yield();
|
||||
time1 = dtime(CLOCK_REALTIME_FAST);
|
||||
time1 = dtime(CLOCK_REALTIME_PRECISE);
|
||||
tick1 = rdtsc();
|
||||
nanosleep(&(struct timespec){0, 1000000}, NULL);
|
||||
time2 = dtime(CLOCK_REALTIME_FAST);
|
||||
time2 = dtime(CLOCK_REALTIME_PRECISE);
|
||||
tick2 = rdtsc();
|
||||
return (time2 - time1) * 1e9 / MAX(1, tick2 - tick1);
|
||||
}
|
||||
@@ -74,13 +74,13 @@ static long double MeasureNanosPerCycle(void) {
|
||||
void RefreshTime(void) {
|
||||
struct Now now;
|
||||
now.cpn = MeasureNanosPerCycle();
|
||||
now.r0 = dtime(CLOCK_REALTIME_FAST);
|
||||
now.r0 = dtime(CLOCK_REALTIME_PRECISE);
|
||||
now.k0 = rdtsc();
|
||||
memcpy(&g_now, &now, sizeof(now));
|
||||
}
|
||||
|
||||
static long double nowl_sys(void) {
|
||||
return dtime(CLOCK_REALTIME_FAST);
|
||||
return dtime(CLOCK_REALTIME_PRECISE);
|
||||
}
|
||||
|
||||
static long double nowl_art(void) {
|
||||
@@ -92,7 +92,7 @@ static long double nowl_vdso(void) {
|
||||
long double secs;
|
||||
struct timespec tv;
|
||||
_unassert(__gettime);
|
||||
__gettime(CLOCK_REALTIME_FAST, &tv);
|
||||
__gettime(CLOCK_REALTIME_PRECISE, &tv);
|
||||
secs = tv.tv_nsec;
|
||||
secs *= 1 / 1e9L;
|
||||
secs += tv.tv_sec;
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
*
|
||||
* @param flags can have R_OK, W_OK, X_OK, etc.
|
||||
* @return 0 if authorized, or -1 w/ errno
|
||||
* @kudos Aaron Ballman for teaching this
|
||||
* @see https://blog.aaronballman.com/2011/08/how-to-check-access-rights/
|
||||
* @see libc/sysv/consts.sh
|
||||
*/
|
||||
textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/ntmagicpaths.internal.h"
|
||||
|
||||
hidden const struct NtMagicPaths kNtMagicPaths = {
|
||||
_Hide const struct NtMagicPaths kNtMagicPaths = {
|
||||
#define TAB(NAME, STRING) STRING,
|
||||
#include "libc/calls/ntmagicpaths.inc"
|
||||
#undef TAB
|
||||
|
||||
@@ -9,7 +9,7 @@ struct NtMagicPaths {
|
||||
#undef TAB
|
||||
};
|
||||
|
||||
hidden extern const struct NtMagicPaths kNtMagicPaths;
|
||||
_Hide extern const struct NtMagicPaths kNtMagicPaths;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -84,7 +84,7 @@ textwindows int ntspawn(
|
||||
sizeof(*block), 0)) &&
|
||||
(block = MapViewOfFileEx(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0,
|
||||
sizeof(*block), 0)) &&
|
||||
mkntcmdline(block->cmdline, prog, argv) != -1 &&
|
||||
mkntcmdline(block->cmdline, argv) != -1 &&
|
||||
mkntenvblock(block->envvars, envp, extravar, block->buf) != -1 &&
|
||||
CreateProcess(prog16, block->cmdline, opt_lpProcessAttributes,
|
||||
opt_lpThreadAttributes, bInheritHandles,
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int mkntcmdline(char16_t[ARG_MAX / 2], const char *, char *const[]) hidden;
|
||||
int mkntcmdline(char16_t[ARG_MAX / 2], char *const[]) _Hide;
|
||||
int mkntenvblock(char16_t[ARG_MAX / 2], char *const[], const char *,
|
||||
char[ARG_MAX]) hidden;
|
||||
char[ARG_MAX]) _Hide;
|
||||
int ntspawn(const char *, char *const[], char *const[], const char *,
|
||||
struct NtSecurityAttributes *, struct NtSecurityAttributes *,
|
||||
bool32, uint32_t, const char16_t *, const struct NtStartupInfo *,
|
||||
struct NtProcessInformation *) hidden;
|
||||
struct NtProcessInformation *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -292,6 +292,7 @@ static const struct thatispacked SyscallName {
|
||||
{__NR_linux_epoll_wait, "epoll_wait"}, //
|
||||
{__NR_linux_epoll_ctl, "epoll_ctl"}, //
|
||||
{__NR_linux_getdents, "getdents"}, //
|
||||
{__NR_linux_oldgetdents, "oldgetdents"}, //
|
||||
{__NR_linux_set_tid_address, "set_tid_address"}, //
|
||||
{__NR_linux_restart_syscall, "restart_syscall"}, //
|
||||
{__NR_linux_semtimedop, "semtimedop"}, //
|
||||
@@ -582,6 +583,7 @@ static const uint16_t kPledgeRpath[] = {
|
||||
__NR_linux_statfs, //
|
||||
__NR_linux_fstatfs, //
|
||||
__NR_linux_getdents, //
|
||||
__NR_linux_oldgetdents, //
|
||||
};
|
||||
|
||||
static const uint16_t kPledgeWpath[] = {
|
||||
@@ -975,13 +977,13 @@ static privileged void OnSigSys(int sig, siginfo_t *si, void *vctx) {
|
||||
if (HasSyscall(kPledge + i, si->si_syscall)) {
|
||||
Log("error: pledge ", kPledge[i].name, " for ",
|
||||
GetSyscallName(si->si_syscall), " (ord=", ord, " rip=", rip, ")\n",
|
||||
0);
|
||||
NULL);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
Log("error: bad syscall (", GetSyscallName(si->si_syscall), " ord=", ord,
|
||||
" rip=", rip, ")\n", 0);
|
||||
" rip=", rip, ")\n", NULL);
|
||||
}
|
||||
switch (mode & PLEDGE_PENALTY_MASK) {
|
||||
case PLEDGE_PENALTY_KILL_PROCESS:
|
||||
|
||||
+5
-2
@@ -24,6 +24,7 @@
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/promises.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/nexgen32e/vendor.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
@@ -238,8 +239,10 @@
|
||||
int pledge(const char *promises, const char *execpromises) {
|
||||
int e, rc;
|
||||
unsigned long ipromises, iexecpromises;
|
||||
if (!ParsePromises(promises, &ipromises) &&
|
||||
!ParsePromises(execpromises, &iexecpromises)) {
|
||||
if (IsGenuineBlink()) {
|
||||
rc = 0; // blink doesn't support seccomp
|
||||
} else if (!ParsePromises(promises, &ipromises) &&
|
||||
!ParsePromises(execpromises, &iexecpromises)) {
|
||||
if (IsLinux()) {
|
||||
// copy exec and execnative from promises to execpromises
|
||||
iexecpromises = ~(~iexecpromises | (~ipromises & (1ul << PROMISE_EXEC)));
|
||||
|
||||
@@ -11,10 +11,10 @@ struct Pledges {
|
||||
const size_t len;
|
||||
};
|
||||
|
||||
hidden extern const struct Pledges kPledge[PROMISE_LEN_];
|
||||
_Hide extern const struct Pledges kPledge[PROMISE_LEN_];
|
||||
|
||||
int sys_pledge_linux(unsigned long, int) hidden;
|
||||
int ParsePromises(const char *, unsigned long *) hidden;
|
||||
int sys_pledge_linux(unsigned long, int) _Hide;
|
||||
int ParsePromises(const char *, unsigned long *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/reparsedatabuffer.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/utf16.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
@@ -45,7 +46,7 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
|
||||
mem = 16384;
|
||||
memory = alloca(mem);
|
||||
for (i = 0; i < mem; i += PAGESIZE) memory[i] = 0;
|
||||
CheckLargeStackAllocation(memory, mem);
|
||||
rdb = (struct NtReparseDataBuffer *)memory;
|
||||
if ((h = CreateFile(path16, 0, 0, 0, kNtOpenExisting,
|
||||
kNtFileFlagOpenReparsePoint | kNtFileFlagBackupSemantics,
|
||||
|
||||
@@ -18,11 +18,11 @@ int sys_sched_get_priority_max(int);
|
||||
int sys_sched_get_priority_min(int);
|
||||
int sys_sched_getparam(int, struct sched_param *);
|
||||
int sys_sched_getscheduler(int);
|
||||
int sys_sched_setaffinity(int, uint64_t, const void *) hidden;
|
||||
int sys_sched_setaffinity(int, uint64_t, const void *) _Hide;
|
||||
int sys_sched_setparam(int, const struct sched_param *);
|
||||
int sys_sched_setscheduler(int, int, const struct sched_param *);
|
||||
int sys_sched_yield(void) hidden;
|
||||
int64_t sys_sched_getaffinity(int, uint64_t, void *) hidden;
|
||||
int sys_sched_yield(void) _Hide;
|
||||
int64_t sys_sched_getaffinity(int, uint64_t, void *) _Hide;
|
||||
|
||||
int sys_sched_getscheduler_netbsd(int, struct sched_param *);
|
||||
int sys_sched_setparam_netbsd(int, int, int, const struct sched_param *) //
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/struct/timespec.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
|
||||
int sys_sched_rr_get_interval(int, struct timespec *) hidden;
|
||||
int sys_sched_rr_get_interval(int, struct timespec *) _Hide;
|
||||
|
||||
/**
|
||||
* Returns round-robin `SCHED_RR` quantum for `pid`.
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -28,14 +28,14 @@ struct Signals {
|
||||
extern struct Signals __sig;
|
||||
extern atomic_long __sig_count;
|
||||
|
||||
bool __sig_check(bool) hidden;
|
||||
bool __sig_handle(bool, int, int, ucontext_t *) hidden;
|
||||
int __sig_add(int, int, int) hidden;
|
||||
int __sig_mask(int, const sigset_t *, sigset_t *) hidden;
|
||||
int __sig_raise(int, int) hidden;
|
||||
void __sig_check_ignore(const int, const unsigned) hidden;
|
||||
void __sig_pending(sigset_t *) hidden;
|
||||
int __sig_is_applicable(struct Signal *) hidden;
|
||||
bool __sig_check(bool) _Hide;
|
||||
bool __sig_handle(bool, int, int, ucontext_t *) _Hide;
|
||||
int __sig_add(int, int, int) _Hide;
|
||||
int __sig_mask(int, const sigset_t *, sigset_t *) _Hide;
|
||||
int __sig_raise(int, int) _Hide;
|
||||
void __sig_check_ignore(const int, const unsigned) _Hide;
|
||||
void __sig_pending(sigset_t *) _Hide;
|
||||
int __sig_is_applicable(struct Signal *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int sys_sigtimedwait(const sigset_t *, union siginfo_meta *,
|
||||
const struct timespec *, size_t) hidden;
|
||||
const struct timespec *, size_t) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
hidden extern int __vforked;
|
||||
hidden extern bool __time_critical;
|
||||
hidden extern unsigned __sighandrvas[NSIG];
|
||||
hidden extern unsigned __sighandflags[NSIG];
|
||||
hidden extern pthread_mutex_t __fds_lock_obj;
|
||||
hidden extern pthread_mutex_t __sig_lock_obj;
|
||||
hidden extern const struct NtSecurityAttributes kNtIsInheritable;
|
||||
_Hide extern int __vforked;
|
||||
_Hide extern bool __time_critical;
|
||||
_Hide extern unsigned __sighandrvas[NSIG];
|
||||
_Hide extern unsigned __sighandflags[NSIG];
|
||||
_Hide extern pthread_mutex_t __fds_lock_obj;
|
||||
_Hide extern pthread_mutex_t __sig_lock_obj;
|
||||
_Hide extern const struct NtSecurityAttributes kNtIsInheritable;
|
||||
|
||||
void __fds_lock(void);
|
||||
void __fds_unlock(void);
|
||||
|
||||
@@ -184,6 +184,10 @@ static const char *DescribeStatfsTypeLinux(int64_t x) {
|
||||
return "xfs";
|
||||
case 0x012fd16d:
|
||||
return "_xiafs";
|
||||
case 0x2fc12fc1:
|
||||
return "zfs";
|
||||
case 0x4253584e:
|
||||
return "apfs";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
@@ -222,7 +226,7 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
|
||||
|
||||
} else if (IsFreebsd()) {
|
||||
f_type = m->freebsd.f_type;
|
||||
f_bsize = m->freebsd.f_bsize;
|
||||
f_bsize = m->freebsd.f_iosize;
|
||||
f_blocks = m->freebsd.f_blocks;
|
||||
f_bfree = m->freebsd.f_bfree;
|
||||
f_bavail = m->freebsd.f_bavail;
|
||||
@@ -237,14 +241,14 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
|
||||
|
||||
} else if (IsXnu()) {
|
||||
f_type = m->xnu.f_type;
|
||||
f_bsize = m->xnu.f_bsize;
|
||||
f_bsize = m->xnu.f_iosize;
|
||||
f_blocks = m->xnu.f_blocks;
|
||||
f_bfree = m->xnu.f_bfree;
|
||||
f_bavail = m->xnu.f_bavail;
|
||||
f_files = m->xnu.f_files;
|
||||
f_ffree = m->xnu.f_ffree;
|
||||
f_fsid = m->xnu.f_fsid;
|
||||
f_namelen = 4096;
|
||||
f_namelen = 255;
|
||||
f_frsize = m->xnu.f_bsize;
|
||||
f_flags = m->xnu.f_flags;
|
||||
f_owner = m->xnu.f_owner;
|
||||
@@ -252,7 +256,7 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
|
||||
|
||||
} else if (IsOpenbsd()) {
|
||||
f_type = f->f_type;
|
||||
f_bsize = m->openbsd.f_bsize;
|
||||
f_bsize = m->openbsd.f_iosize;
|
||||
f_blocks = m->openbsd.f_blocks;
|
||||
f_bfree = m->openbsd.f_bfree;
|
||||
f_bavail = m->openbsd.f_bavail;
|
||||
@@ -267,7 +271,7 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
|
||||
|
||||
} else if (IsNetbsd()) {
|
||||
f_type = m->netbsd.f_type;
|
||||
f_bsize = m->netbsd.f_bsize;
|
||||
f_bsize = m->netbsd.f_iosize;
|
||||
f_blocks = m->netbsd.f_blocks;
|
||||
f_bfree = m->netbsd.f_bfree;
|
||||
f_bavail = m->netbsd.f_bavail;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_FRAMEBUFFERCOLORMAP_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_FRAMEBUFFERCOLORMAP_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
struct FrameBufferColorMap {
|
||||
uint32_t start;
|
||||
uint32_t len;
|
||||
uint16_t *red;
|
||||
uint16_t *green;
|
||||
uint16_t *blue;
|
||||
uint16_t *transp;
|
||||
};
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_FRAMEBUFFERCOLORMAP_H_ */
|
||||
@@ -6,24 +6,24 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int64_t sys_preadv(int, struct iovec *, int, int64_t, int64_t) hidden;
|
||||
int64_t sys_pwritev(int, const struct iovec *, int, int64_t, int64_t) hidden;
|
||||
int64_t sys_readv(int32_t, const struct iovec *, int32_t) hidden;
|
||||
int64_t sys_vmsplice(int, const struct iovec *, int64_t, uint32_t) hidden;
|
||||
int64_t sys_writev(int32_t, const struct iovec *, int32_t) hidden;
|
||||
size_t __iovec_size(const struct iovec *, size_t) hidden;
|
||||
int64_t sys_preadv(int, struct iovec *, int, int64_t, int64_t) _Hide;
|
||||
int64_t sys_pwritev(int, const struct iovec *, int, int64_t, int64_t) _Hide;
|
||||
int64_t sys_readv(int32_t, const struct iovec *, int32_t) _Hide;
|
||||
int64_t sys_vmsplice(int, const struct iovec *, int64_t, uint32_t) _Hide;
|
||||
int64_t sys_writev(int32_t, const struct iovec *, int32_t) _Hide;
|
||||
size_t __iovec_size(const struct iovec *, size_t) _Hide;
|
||||
ssize_t WritevUninterruptible(int, struct iovec *, int);
|
||||
ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
|
||||
ssize_t sys_readv_metal(struct Fd *, const struct iovec *, int) hidden;
|
||||
ssize_t sys_readv_nt(struct Fd *, const struct iovec *, int) hidden;
|
||||
ssize_t sys_readv_serial(struct Fd *, const struct iovec *, int) hidden;
|
||||
ssize_t sys_write_nt(int, const struct iovec *, size_t, ssize_t) hidden;
|
||||
ssize_t sys_writev_metal(struct Fd *, const struct iovec *, int) hidden;
|
||||
ssize_t sys_writev_nt(int, const struct iovec *, int) hidden;
|
||||
ssize_t sys_writev_serial(struct Fd *, const struct iovec *, int) hidden;
|
||||
ssize_t sys_send_nt(int, const struct iovec *, size_t, uint32_t) hidden;
|
||||
ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, ssize_t) _Hide;
|
||||
ssize_t sys_readv_metal(struct Fd *, const struct iovec *, int) _Hide;
|
||||
ssize_t sys_readv_nt(struct Fd *, const struct iovec *, int) _Hide;
|
||||
ssize_t sys_readv_serial(struct Fd *, const struct iovec *, int) _Hide;
|
||||
ssize_t sys_write_nt(int, const struct iovec *, size_t, ssize_t) _Hide;
|
||||
ssize_t sys_writev_metal(struct Fd *, const struct iovec *, int) _Hide;
|
||||
ssize_t sys_writev_nt(int, const struct iovec *, int) _Hide;
|
||||
ssize_t sys_writev_serial(struct Fd *, const struct iovec *, int) _Hide;
|
||||
ssize_t sys_send_nt(int, const struct iovec *, size_t, uint32_t) _Hide;
|
||||
ssize_t sys_sendto_nt(int, const struct iovec *, size_t, uint32_t, void *,
|
||||
uint32_t) hidden;
|
||||
uint32_t) _Hide;
|
||||
|
||||
const char *DescribeIovec(char[300], ssize_t, const struct iovec *, int);
|
||||
#define DescribeIovec(x, y, z) DescribeIovec(alloca(300), x, y, z)
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int sys_getitimer(int, struct itimerval *) hidden;
|
||||
int sys_setitimer(int, const struct itimerval *, struct itimerval *) hidden;
|
||||
int sys_setitimer_nt(int, const struct itimerval *, struct itimerval *) hidden;
|
||||
int sys_getitimer(int, struct itimerval *) _Hide;
|
||||
int sys_setitimer(int, const struct itimerval *, struct itimerval *) _Hide;
|
||||
int sys_setitimer_nt(int, const struct itimerval *, struct itimerval *) _Hide;
|
||||
|
||||
const char *DescribeTimeval(char[45], int, const struct timeval *);
|
||||
#define DescribeTimeval(rc, ts) DescribeTimeval(alloca(45), rc, ts)
|
||||
|
||||
@@ -94,7 +94,7 @@ union metastat {
|
||||
struct stat_netbsd netbsd;
|
||||
};
|
||||
|
||||
void __stat2cosmo(struct stat *restrict, const union metastat *) hidden;
|
||||
void __stat2cosmo(struct stat *restrict, const union metastat *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int sys_getrlimit(int, struct rlimit *) hidden;
|
||||
int sys_setrlimit(int, const struct rlimit *) hidden;
|
||||
int sys_setrlimit_nt(int, const struct rlimit *) hidden;
|
||||
int sys_getrlimit(int, struct rlimit *) _Hide;
|
||||
int sys_setrlimit(int, const struct rlimit *) _Hide;
|
||||
int sys_setrlimit_nt(int, const struct rlimit *) _Hide;
|
||||
|
||||
const char *DescribeRlimit(char[64], int, const struct rlimit *);
|
||||
#define DescribeRlimit(rc, rl) DescribeRlimit(alloca(64), rc, rl)
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int __sys_getrusage(int, struct rusage *) hidden;
|
||||
int __sys_wait4(int, int *, int, struct rusage *) hidden;
|
||||
int sys_getrusage(int, struct rusage *) hidden;
|
||||
int sys_wait4(int, int *, int, struct rusage *) hidden;
|
||||
void __rusage2linux(struct rusage *) hidden;
|
||||
int sys_getrusage_nt(int, struct rusage *) hidden;
|
||||
int __sys_getrusage(int, struct rusage *) _Hide;
|
||||
int __sys_wait4(int, int *, int, struct rusage *) _Hide;
|
||||
int sys_getrusage(int, struct rusage *) _Hide;
|
||||
int sys_wait4(int, int *, int, struct rusage *) _Hide;
|
||||
void __rusage2linux(struct rusage *) _Hide;
|
||||
int sys_getrusage_nt(int, struct rusage *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -54,11 +54,11 @@ union metasigaction {
|
||||
struct sigaction_xnu_out xnu_out;
|
||||
};
|
||||
|
||||
void __sigenter_xnu(int, struct siginfo *, void *) hidden;
|
||||
void __sigenter_wsl(int, struct siginfo *, void *) hidden;
|
||||
void __sigenter_netbsd(int, struct siginfo *, void *) hidden;
|
||||
void __sigenter_freebsd(int, struct siginfo *, void *) hidden;
|
||||
void __sigenter_openbsd(int, struct siginfo *, void *) hidden;
|
||||
void __sigenter_xnu(int, struct siginfo *, void *) _Hide;
|
||||
void __sigenter_wsl(int, struct siginfo *, void *) _Hide;
|
||||
void __sigenter_netbsd(int, struct siginfo *, void *) _Hide;
|
||||
void __sigenter_freebsd(int, struct siginfo *, void *) _Hide;
|
||||
void __sigenter_openbsd(int, struct siginfo *, void *) _Hide;
|
||||
|
||||
const char *DescribeSigaction(char[256], int, const struct sigaction *);
|
||||
#define DescribeSigaction(rc, sa) DescribeSigaction(alloca(256), rc, sa)
|
||||
|
||||
@@ -16,7 +16,7 @@ union siginfo_meta {
|
||||
struct siginfo_netbsd netbsd;
|
||||
};
|
||||
|
||||
void __siginfo2cosmo(struct siginfo *, const union siginfo_meta *) hidden;
|
||||
void __siginfo2cosmo(struct siginfo *, const union siginfo_meta *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int sys_sigqueueinfo(int, const siginfo_t *) hidden;
|
||||
int sys_sigqueueinfo(int, const siginfo_t *) _Hide;
|
||||
|
||||
const char *DescribeSiginfo(char[300], int, const siginfo_t *);
|
||||
#define DescribeSiginfo(x, y) DescribeSiginfo(alloca(300), x, y)
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int __sys_sigprocmask(int, const struct sigset *, struct sigset *,
|
||||
uint64_t) hidden;
|
||||
int sys_sigprocmask(int, const struct sigset *, struct sigset *) hidden;
|
||||
int sys_sigsuspend(const struct sigset *, uint64_t) hidden;
|
||||
int sys_sigpending(struct sigset *, size_t) hidden;
|
||||
uint64_t) _Hide;
|
||||
int sys_sigprocmask(int, const struct sigset *, struct sigset *) _Hide;
|
||||
int sys_sigsuspend(const struct sigset *, uint64_t) _Hide;
|
||||
int sys_sigpending(struct sigset *, size_t) _Hide;
|
||||
|
||||
const char *DescribeSigset(char[128], int, const sigset_t *);
|
||||
#define DescribeSigset(rc, ss) DescribeSigset(alloca(128), rc, ss)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int sys_sigqueue(int, int, const union sigval) hidden;
|
||||
int sys_sigqueue(int, int, const union sigval) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int sys_fstat(int, struct stat *) hidden;
|
||||
int sys_fstatat(int, const char *, struct stat *, int) hidden;
|
||||
int sys_fstat_nt(int64_t, struct stat *) hidden;
|
||||
int sys_fstatat_nt(int, const char *, struct stat *, int) hidden;
|
||||
int sys_lstat_nt(const char *, struct stat *) hidden;
|
||||
int sys_fstat(int, struct stat *) _Hide;
|
||||
int sys_fstatat(int, const char *, struct stat *, int) _Hide;
|
||||
int sys_fstat_nt(int64_t, struct stat *) _Hide;
|
||||
int sys_fstatat_nt(int, const char *, struct stat *, int) _Hide;
|
||||
int sys_lstat_nt(const char *, struct stat *) _Hide;
|
||||
int sys_fstat_metal(int, struct stat *);
|
||||
|
||||
const char *DescribeStat(char[300], int, const struct stat *);
|
||||
|
||||
@@ -9,7 +9,7 @@ struct statfs_linux {
|
||||
int64_t f_bsize; /* optimal transfer block size */
|
||||
int64_t f_blocks; /* total data blocks in filesystem */
|
||||
int64_t f_bfree; /* free blocks in filesystem */
|
||||
int64_t f_bavail; /* free blocks available to */
|
||||
int64_t f_bavail; /* free blocks available to unprivileged user */
|
||||
int64_t f_files; /* total file nodes in filesystem */
|
||||
int64_t f_ffree; /* free file nodes in filesystem */
|
||||
fsid_t f_fsid; /* filesystem id */
|
||||
|
||||
@@ -17,7 +17,7 @@ union statfs_meta {
|
||||
struct statfs_netbsd netbsd;
|
||||
};
|
||||
|
||||
void statfs2cosmo(struct statfs *, const union statfs_meta *) hidden;
|
||||
void statfs2cosmo(struct statfs *, const union statfs_meta *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -13,7 +13,8 @@ struct sysinfo {
|
||||
uint64_t totalswap; /* size of emergency memory */
|
||||
uint64_t freeswap; /* hopefully equal to totalswap */
|
||||
int16_t procs; /* number of processes */
|
||||
int16_t __ignore; /* padding */
|
||||
int16_t __ignore1; /* padding */
|
||||
int32_t __ignore2; /* padding */
|
||||
uint64_t totalhigh; /* wut */
|
||||
uint64_t freehigh; /* wut */
|
||||
uint32_t mem_unit; /* ram stuff above is multiples of this */
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int sys_sysinfo(struct sysinfo *) hidden;
|
||||
int sys_sysinfo_nt(struct sysinfo *) hidden;
|
||||
int sys_sysinfo(struct sysinfo *) _Hide;
|
||||
int sys_sysinfo_nt(struct sysinfo *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -6,24 +6,24 @@
|
||||
COSMOPOLITAN_C_START_
|
||||
/* clang-format off */
|
||||
|
||||
int __sys_utimensat(int, const char *, const struct timespec[2], int) hidden;
|
||||
int __utimens(int, const char *, const struct timespec[2], int) hidden;
|
||||
int sys_clock_getres(int, struct timespec *) hidden;
|
||||
int sys_clock_gettime(int, struct timespec *) hidden;
|
||||
int sys_clock_gettime_nt(int, struct timespec *) hidden;
|
||||
int sys_clock_gettime_xnu(int, struct timespec *) hidden;
|
||||
int sys_clock_nanosleep(int, int, const struct timespec *, struct timespec *) hidden;
|
||||
int sys_clock_nanosleep_nt(int, int, const struct timespec *, struct timespec *) hidden;
|
||||
int sys_clock_nanosleep_openbsd(int, int, const struct timespec *, struct timespec *) hidden;
|
||||
int sys_clock_nanosleep_xnu(int, int, const struct timespec *, struct timespec *) hidden;
|
||||
int sys_futimens(int, const struct timespec[2]) hidden;
|
||||
int sys_nanosleep(const struct timespec *, struct timespec *) hidden;
|
||||
int sys_nanosleep_nt(const struct timespec *, struct timespec *) hidden;
|
||||
int sys_nanosleep_xnu(const struct timespec *, struct timespec *) hidden;
|
||||
int sys_sem_timedwait(int64_t, const struct timespec *) hidden;
|
||||
int sys_utimensat(int, const char *, const struct timespec[2], int) hidden;
|
||||
int sys_utimensat_nt(int, const char *, const struct timespec[2], int) hidden;
|
||||
int sys_utimensat_xnu(int, const char *, const struct timespec[2], int) hidden;
|
||||
int __sys_clock_nanosleep(int, int, const struct timespec *, struct timespec *) _Hide;
|
||||
int __sys_utimensat(int, const char *, const struct timespec[2], int) _Hide;
|
||||
int __utimens(int, const char *, const struct timespec[2], int) _Hide;
|
||||
int sys_clock_getres(int, struct timespec *) _Hide;
|
||||
int sys_clock_gettime(int, struct timespec *) _Hide;
|
||||
int sys_clock_gettime_nt(int, struct timespec *) _Hide;
|
||||
int sys_clock_gettime_xnu(int, struct timespec *) _Hide;
|
||||
int sys_clock_nanosleep_nt(int, int, const struct timespec *, struct timespec *) _Hide;
|
||||
int sys_clock_nanosleep_openbsd(int, int, const struct timespec *, struct timespec *) _Hide;
|
||||
int sys_clock_nanosleep_xnu(int, int, const struct timespec *, struct timespec *) _Hide;
|
||||
int sys_futimens(int, const struct timespec[2]) _Hide;
|
||||
int sys_nanosleep(const struct timespec *, struct timespec *) _Hide;
|
||||
int sys_nanosleep_nt(const struct timespec *, struct timespec *) _Hide;
|
||||
int sys_nanosleep_xnu(const struct timespec *, struct timespec *) _Hide;
|
||||
int sys_sem_timedwait(int64_t, const struct timespec *) _Hide;
|
||||
int sys_utimensat(int, const char *, const struct timespec[2], int) _Hide;
|
||||
int sys_utimensat_nt(int, const char *, const struct timespec[2], int) _Hide;
|
||||
int sys_utimensat_xnu(int, const char *, const struct timespec[2], int) _Hide;
|
||||
|
||||
const char *DescribeTimespec(char[45], int, const struct timespec *);
|
||||
#define DescribeTimespec(rc, ts) DescribeTimespec(alloca(45), rc, ts)
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
axdx_t sys_gettimeofday(struct timeval *, struct timezone *, void *) hidden;
|
||||
int sys_futimes(int, const struct timeval *) hidden;
|
||||
int sys_futimesat(int, const char *, const struct timeval *) hidden;
|
||||
int sys_lutimes(const char *, const struct timeval *) hidden;
|
||||
int sys_utimes(const char *, const struct timeval *) hidden;
|
||||
axdx_t sys_gettimeofday_xnu(struct timeval *, struct timezone *, void *) hidden;
|
||||
axdx_t sys_gettimeofday_nt(struct timeval *, struct timezone *, void *) hidden;
|
||||
int sys_utimes_nt(const char *, const struct timeval[2]) hidden;
|
||||
axdx_t sys_gettimeofday(struct timeval *, struct timezone *, void *) _Hide;
|
||||
int sys_futimes(int, const struct timeval *) _Hide;
|
||||
int sys_futimesat(int, const char *, const struct timeval *) _Hide;
|
||||
int sys_lutimes(const char *, const struct timeval *) _Hide;
|
||||
int sys_utimes(const char *, const struct timeval *) _Hide;
|
||||
axdx_t sys_gettimeofday_xnu(struct timeval *, struct timezone *, void *) _Hide;
|
||||
axdx_t sys_gettimeofday_nt(struct timeval *, struct timezone *, void *) _Hide;
|
||||
int sys_utimes_nt(const char *, const struct timeval[2]) _Hide;
|
||||
axdx_t sys_gettimeofday_metal(struct timeval *, struct timezone *, void *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
void _ntcontext2linux(struct ucontext *, const struct NtContext *) hidden;
|
||||
void _ntlinux2context(struct NtContext *, const ucontext_t *) hidden;
|
||||
void _ntcontext2linux(struct ucontext *, const struct NtContext *) _Hide;
|
||||
void _ntlinux2context(struct NtContext *, const ucontext_t *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
Whitespace-only changes.
@@ -5,7 +5,7 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) hidden;
|
||||
int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -3,40 +3,40 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
bool32 sys_isatty_nt(int) hidden;
|
||||
char *sys_getcwd_nt(char *, size_t) hidden;
|
||||
int sys_chdir_nt(const char *) hidden;
|
||||
int sys_close_epoll_nt(int) hidden;
|
||||
int sys_dup_nt(int, int, int, int) hidden;
|
||||
int sys_execve_nt(const char *, char *const[], char *const[]) hidden;
|
||||
int sys_faccessat_nt(int, const char *, int, uint32_t) hidden;
|
||||
int sys_fadvise_nt(int, uint64_t, uint64_t, int) hidden;
|
||||
int sys_fchdir_nt(int) hidden;
|
||||
int sys_fchmodat_nt(int, const char *, uint32_t, int) hidden;
|
||||
int sys_fcntl_nt(int, int, uintptr_t) hidden;
|
||||
int sys_fdatasync_nt(int) hidden;
|
||||
int sys_flock_nt(int, int) hidden;
|
||||
int sys_fork_nt(uint32_t) hidden;
|
||||
int sys_ftruncate_nt(int64_t, uint64_t) hidden;
|
||||
int sys_getloadavg_nt(double *, int) hidden;
|
||||
int sys_getppid_nt(void) hidden;
|
||||
int sys_getpriority_nt(int, unsigned) hidden;
|
||||
int sys_kill_nt(int, int) hidden;
|
||||
int sys_linkat_nt(int, const char *, int, const char *) hidden;
|
||||
int sys_madvise_nt(void *, size_t, int) hidden;
|
||||
int sys_mkdirat_nt(int, const char *, uint32_t) hidden;
|
||||
int sys_msync_nt(char *, size_t, int) hidden;
|
||||
int sys_open_nt(int, const char *, uint32_t, int32_t) dontdiscard hidden;
|
||||
int sys_pipe_nt(int[hasatleast 2], unsigned) hidden;
|
||||
int sys_renameat_nt(int, const char *, int, const char *) hidden;
|
||||
int sys_sched_yield_nt(void) hidden;
|
||||
int sys_setpriority_nt(int, unsigned, int) hidden;
|
||||
int sys_symlinkat_nt(const char *, int, const char *) hidden;
|
||||
int sys_sync_nt(void) hidden;
|
||||
int sys_truncate_nt(const char *, uint64_t) hidden;
|
||||
int sys_unlinkat_nt(int, const char *, int) hidden;
|
||||
int64_t sys_lseek_nt(int, int64_t, int) hidden;
|
||||
ssize_t sys_readlinkat_nt(int, const char *, char *, size_t) hidden;
|
||||
bool32 sys_isatty_nt(int) _Hide;
|
||||
char *sys_getcwd_nt(char *, size_t) _Hide;
|
||||
int sys_chdir_nt(const char *) _Hide;
|
||||
int sys_close_epoll_nt(int) _Hide;
|
||||
int sys_dup_nt(int, int, int, int) _Hide;
|
||||
int sys_execve_nt(const char *, char *const[], char *const[]) _Hide;
|
||||
int sys_faccessat_nt(int, const char *, int, uint32_t) _Hide;
|
||||
int sys_fadvise_nt(int, uint64_t, uint64_t, int) _Hide;
|
||||
int sys_fchdir_nt(int) _Hide;
|
||||
int sys_fchmodat_nt(int, const char *, uint32_t, int) _Hide;
|
||||
int sys_fcntl_nt(int, int, uintptr_t) _Hide;
|
||||
int sys_fdatasync_nt(int) _Hide;
|
||||
int sys_flock_nt(int, int) _Hide;
|
||||
int sys_fork_nt(uint32_t) _Hide;
|
||||
int sys_ftruncate_nt(int64_t, uint64_t) _Hide;
|
||||
int sys_getloadavg_nt(double *, int) _Hide;
|
||||
int sys_getppid_nt(void) _Hide;
|
||||
int sys_getpriority_nt(int, unsigned) _Hide;
|
||||
int sys_kill_nt(int, int) _Hide;
|
||||
int sys_linkat_nt(int, const char *, int, const char *) _Hide;
|
||||
int sys_madvise_nt(void *, size_t, int) _Hide;
|
||||
int sys_mkdirat_nt(int, const char *, uint32_t) _Hide;
|
||||
int sys_msync_nt(char *, size_t, int) _Hide;
|
||||
int sys_open_nt(int, const char *, uint32_t, int32_t) dontdiscard _Hide;
|
||||
int sys_pipe_nt(int[hasatleast 2], unsigned) _Hide;
|
||||
int sys_renameat_nt(int, const char *, int, const char *) _Hide;
|
||||
int sys_sched_yield_nt(void) _Hide;
|
||||
int sys_setpriority_nt(int, unsigned, int) _Hide;
|
||||
int sys_symlinkat_nt(const char *, int, const char *) _Hide;
|
||||
int sys_sync_nt(void) _Hide;
|
||||
int sys_truncate_nt(const char *, uint64_t) _Hide;
|
||||
int sys_unlinkat_nt(int, const char *, int) _Hide;
|
||||
int64_t sys_lseek_nt(int, int64_t, int) _Hide;
|
||||
ssize_t sys_readlinkat_nt(int, const char *, char *, size_t) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
+130
-127
@@ -10,133 +10,136 @@ COSMOPOLITAN_C_START_
|
||||
│ cosmopolitan § syscalls » system five » structless synthetic jump slots ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
axdx_t __sys_fork(void) hidden;
|
||||
axdx_t __sys_pipe(i32[hasatleast 2], i32) hidden;
|
||||
axdx_t sys_getpid(void) hidden;
|
||||
char *sys_getcwd(char *, u64) hidden;
|
||||
char *sys_getcwd_xnu(char *, u64) hidden;
|
||||
i32 __sys_dup3(i32, i32, i32) hidden;
|
||||
i32 __sys_execve(const char *, char *const[], char *const[]) hidden;
|
||||
i32 __sys_fcntl(i32, i32, ...) hidden;
|
||||
i32 __sys_fcntl_cp(i32, i32, ...) hidden;
|
||||
i32 __sys_fstat(i32, void *) hidden;
|
||||
i32 __sys_fstatat(i32, const char *, void *, i32) hidden;
|
||||
i32 __sys_gettid(i64 *) hidden;
|
||||
i32 __sys_munmap(void *, u64) hidden;
|
||||
i32 __sys_openat(i32, const char *, i32, u32) hidden;
|
||||
i32 __sys_openat_nc(i32, const char *, i32, u32) hidden;
|
||||
i32 __sys_pipe2(i32[hasatleast 2], u32) hidden;
|
||||
i32 sys_arch_prctl(i32, i64) hidden;
|
||||
i32 sys_chdir(const char *) hidden;
|
||||
i32 sys_chroot(const char *) hidden;
|
||||
i32 sys_close(i32) hidden;
|
||||
i32 sys_close_range(u32, u32, u32) hidden;
|
||||
i32 sys_closefrom(i32) hidden;
|
||||
i32 sys_creat(const char *, u32) hidden;
|
||||
i32 sys_dup(i32) hidden;
|
||||
i32 sys_dup2(i32, i32) hidden;
|
||||
i32 sys_dup3(i32, i32, i32) hidden;
|
||||
i32 sys_execve(const char *, char *const[], char *const[]) hidden;
|
||||
i32 sys_faccessat(i32, const char *, i32, u32) hidden;
|
||||
i32 sys_faccessat2(i32, const char *, i32, u32) hidden;
|
||||
i32 sys_fadvise(i32, i64, i64, i32) hidden;
|
||||
i32 sys_fchdir(i32) hidden;
|
||||
i32 sys_fchmod(i32, u32) hidden;
|
||||
i32 sys_fchmodat(i32, const char *, u32, u32) hidden;
|
||||
i32 sys_fchown(i64, u32, u32) hidden;
|
||||
i32 sys_fchownat(i32, const char *, u32, u32, u32) hidden;
|
||||
i32 sys_fcntl(i32, i32, u64, i32 (*)(i32, i32, ...)) hidden;
|
||||
i32 sys_fdatasync(i32) hidden;
|
||||
i32 sys_flock(i32, i32) hidden;
|
||||
i32 sys_fork(void) hidden;
|
||||
i32 sys_fsync(i32) hidden;
|
||||
i32 sys_ftruncate(i32, i64, i64) hidden;
|
||||
i32 sys_getcontext(void *) hidden;
|
||||
i32 sys_getpgid(i32) hidden;
|
||||
i32 sys_getpgrp(void) hidden;
|
||||
i32 sys_getppid(void) hidden;
|
||||
i32 sys_getpriority(i32, u32) hidden;
|
||||
i32 sys_getresgid(u32 *, u32 *, u32 *) hidden;
|
||||
i32 sys_getresuid(u32 *, u32 *, u32 *) hidden;
|
||||
i32 sys_getsid(i32) hidden;
|
||||
i32 sys_gettid(void) hidden;
|
||||
i32 sys_ioctl(i32, u64, ...) hidden;
|
||||
i32 sys_ioctl_cp(i32, u64, ...) hidden;
|
||||
i32 sys_issetugid(void) hidden;
|
||||
i32 sys_kill(i32, i32, i32) hidden;
|
||||
i32 sys_linkat(i32, const char *, i32, const char *, i32) hidden;
|
||||
i32 sys_madvise(void *, size_t, i32) hidden;
|
||||
i32 sys_memfd_create(const char *, u32) hidden;
|
||||
i32 sys_mincore(void *, u64, unsigned char *) hidden;
|
||||
i32 sys_mkdirat(i32, const char *, u32) hidden;
|
||||
i32 sys_mkfifo(const char *, u32) hidden;
|
||||
i32 sys_mknod(const char *, u32, u64) hidden;
|
||||
i32 sys_mprotect(void *, u64, i32) hidden;
|
||||
i32 sys_msync(void *, u64, i32) hidden;
|
||||
i32 sys_munmap(void *, u64) hidden;
|
||||
i32 sys_open(const char *, i32, u32) hidden;
|
||||
i32 sys_openat(i32, const char *, i32, u32) hidden;
|
||||
i32 sys_pause(void) hidden;
|
||||
i32 sys_pipe(i32[hasatleast 2]) hidden;
|
||||
i32 sys_pipe2(i32[hasatleast 2], u32) hidden;
|
||||
i32 sys_pivot_root(const char *, const char *) hidden;
|
||||
i32 sys_pledge(const char *, const char *) hidden;
|
||||
i32 sys_posix_openpt(i32) hidden;
|
||||
i32 sys_renameat(i32, const char *, i32, const char *) hidden;
|
||||
i32 sys_sem_close(i64) hidden;
|
||||
i32 sys_sem_destroy(i64) hidden;
|
||||
i32 sys_sem_getvalue(i64, u32 *) hidden;
|
||||
i32 sys_sem_init(u32, i64 *) hidden;
|
||||
i32 sys_sem_open(const char *, int, u32, i64 *) hidden;
|
||||
i32 sys_sem_post(i64) hidden;
|
||||
i32 sys_sem_trywait(i64) hidden;
|
||||
i32 sys_sem_unlink(const char *) hidden;
|
||||
i32 sys_sem_wait(i64) hidden;
|
||||
i32 sys_setfsgid(i32) hidden;
|
||||
i32 sys_setfsuid(i32) hidden;
|
||||
i32 sys_setgid(i32) hidden;
|
||||
i32 sys_setpgid(i32, i32) hidden;
|
||||
i32 sys_setpriority(i32, u32, i32) hidden;
|
||||
i32 sys_setregid(u32, u32) hidden;
|
||||
i32 sys_setresgid(u32, u32, u32) hidden;
|
||||
i32 sys_setresuid(u32, u32, u32) hidden;
|
||||
i32 sys_setreuid(u32, u32) hidden;
|
||||
i32 sys_setsid(void) hidden;
|
||||
i32 sys_setuid(i32) hidden;
|
||||
i32 sys_sigaction(i32, const void *, void *, i64, i64) hidden;
|
||||
i32 sys_sigaltstack(const void *, void *) hidden;
|
||||
i32 sys_symlinkat(const char *, i32, const char *) hidden;
|
||||
i32 sys_sync(void) hidden;
|
||||
i32 sys_sync_file_range(i32, i64, i64, u32) hidden;
|
||||
i32 sys_syslog(i32, char *, i32) hidden;
|
||||
i32 sys_tgkill(i32, i32, i32) hidden;
|
||||
i32 sys_tkill(i32, i32, void *) hidden;
|
||||
i32 sys_truncate(const char *, u64, u64) hidden;
|
||||
i32 sys_uname(void *) hidden;
|
||||
i32 sys_unlink(const char *) hidden;
|
||||
i32 sys_unlinkat(i32, const char *, i32) hidden;
|
||||
i32 sys_unmount(const char *, i32) hidden;
|
||||
i32 sys_unveil(const char *, const char *) hidden;
|
||||
i64 __sys_ptrace(i32, i32, i64, long *) hidden;
|
||||
i64 sys_copy_file_range(i32, long *, i32, long *, u64, u32) hidden;
|
||||
i64 sys_getrandom(void *, u64, u32) hidden;
|
||||
i64 sys_lseek(i32, i64, i64, i64) hidden;
|
||||
i64 sys_pread(i32, void *, u64, i64, i64) hidden;
|
||||
i64 sys_pwrite(i32, const void *, u64, i64, i64) hidden;
|
||||
i64 sys_read(i32, void *, u64) hidden;
|
||||
i64 sys_readlink(const char *, char *, u64) hidden;
|
||||
i64 sys_readlinkat(i32, const char *, char *, u64) hidden;
|
||||
i64 sys_sendfile(i32, i32, i64 *, u64) hidden;
|
||||
i64 sys_splice(i32, i64 *, i32, i64 *, u64, u32) hidden;
|
||||
i64 sys_write(i32, const void *, u64) hidden;
|
||||
u32 sys_getegid(void) hidden;
|
||||
u32 sys_geteuid(void) hidden;
|
||||
u32 sys_getgid(void) hidden;
|
||||
u32 sys_getuid(void) hidden;
|
||||
u32 sys_umask(u32) hidden;
|
||||
void *__sys_mmap(void *, u64, u32, u32, i64, i64, i64) hidden;
|
||||
void *sys_mremap(void *, u64, u64, i32, void *) hidden;
|
||||
void sys_exit(i32) hidden;
|
||||
axdx_t __sys_fork(void) _Hide;
|
||||
axdx_t __sys_pipe(i32[hasatleast 2], i32) _Hide;
|
||||
axdx_t sys_getpid(void) _Hide;
|
||||
char *sys_getcwd(char *, u64) _Hide;
|
||||
char *sys_getcwd_xnu(char *, u64) _Hide;
|
||||
i32 __sys_dup3(i32, i32, i32) _Hide;
|
||||
i32 __sys_execve(const char *, char *const[], char *const[]) _Hide;
|
||||
i32 __sys_fcntl(i32, i32, ...) _Hide;
|
||||
i32 __sys_fcntl_cp(i32, i32, ...) _Hide;
|
||||
i32 __sys_fstat(i32, void *) _Hide;
|
||||
i32 __sys_fstatat(i32, const char *, void *, i32) _Hide;
|
||||
i32 __sys_gettid(i64 *) _Hide;
|
||||
i32 __sys_munmap(void *, u64) _Hide;
|
||||
i32 __sys_openat(i32, const char *, i32, u32) _Hide;
|
||||
i32 __sys_openat_nc(i32, const char *, i32, u32) _Hide;
|
||||
i32 __sys_pipe2(i32[hasatleast 2], u32) _Hide;
|
||||
i32 sys_arch_prctl(i32, i64) _Hide;
|
||||
i32 sys_chdir(const char *) _Hide;
|
||||
i32 sys_chroot(const char *) _Hide;
|
||||
i32 sys_close(i32) _Hide;
|
||||
i32 sys_close_range(u32, u32, u32) _Hide;
|
||||
i32 sys_closefrom(i32) _Hide;
|
||||
i32 sys_creat(const char *, u32) _Hide;
|
||||
i32 sys_dup(i32) _Hide;
|
||||
i32 sys_dup2(i32, i32) _Hide;
|
||||
i32 sys_dup3(i32, i32, i32) _Hide;
|
||||
i32 sys_execve(const char *, char *const[], char *const[]) _Hide;
|
||||
i32 sys_execveat(i32, const char *, char *const[], char *const[], i32) _Hide;
|
||||
i32 sys_faccessat(i32, const char *, i32, u32) _Hide;
|
||||
i32 sys_faccessat2(i32, const char *, i32, u32) _Hide;
|
||||
i32 sys_fadvise(i32, i64, i64, i32) _Hide;
|
||||
i32 sys_fchdir(i32) _Hide;
|
||||
i32 sys_fchmod(i32, u32) _Hide;
|
||||
i32 sys_fchmodat(i32, const char *, u32, u32) _Hide;
|
||||
i32 sys_fchown(i64, u32, u32) _Hide;
|
||||
i32 sys_fchownat(i32, const char *, u32, u32, u32) _Hide;
|
||||
i32 sys_fcntl(i32, i32, u64, i32 (*)(i32, i32, ...)) _Hide;
|
||||
i32 sys_fdatasync(i32) _Hide;
|
||||
i32 sys_fexecve(i32, char *const[], char *const[]) _Hide;
|
||||
i32 sys_flock(i32, i32) _Hide;
|
||||
i32 sys_fork(void) _Hide;
|
||||
i32 sys_fsync(i32) _Hide;
|
||||
i32 sys_ftruncate(i32, i64, i64) _Hide;
|
||||
i32 sys_getcontext(void *) _Hide;
|
||||
i32 sys_getpgid(i32) _Hide;
|
||||
i32 sys_getpgrp(void) _Hide;
|
||||
i32 sys_getppid(void) _Hide;
|
||||
i32 sys_getpriority(i32, u32) _Hide;
|
||||
i32 sys_getresgid(u32 *, u32 *, u32 *) _Hide;
|
||||
i32 sys_getresuid(u32 *, u32 *, u32 *) _Hide;
|
||||
i32 sys_getsid(i32) _Hide;
|
||||
i32 sys_gettid(void) _Hide;
|
||||
i32 sys_ioctl(i32, u64, ...) _Hide;
|
||||
i32 sys_ioctl_cp(i32, u64, ...) _Hide;
|
||||
i32 sys_issetugid(void) _Hide;
|
||||
i32 sys_kill(i32, i32, i32) _Hide;
|
||||
i32 sys_linkat(i32, const char *, i32, const char *, i32) _Hide;
|
||||
i32 sys_madvise(void *, size_t, i32) _Hide;
|
||||
i32 sys_memfd_create(const char *, u32) _Hide;
|
||||
i32 sys_mincore(void *, u64, unsigned char *) _Hide;
|
||||
i32 sys_mkdirat(i32, const char *, u32) _Hide;
|
||||
i32 sys_mkfifo(const char *, u32) _Hide;
|
||||
i32 sys_mknod(const char *, u32, u64) _Hide;
|
||||
i32 sys_mprotect(void *, u64, i32) _Hide;
|
||||
i32 sys_msync(void *, u64, i32) _Hide;
|
||||
i32 sys_munmap(void *, u64) _Hide;
|
||||
i32 sys_open(const char *, i32, u32) _Hide;
|
||||
i32 sys_openat(i32, const char *, i32, u32) _Hide;
|
||||
i32 sys_pause(void) _Hide;
|
||||
i32 sys_pipe(i32[hasatleast 2]) _Hide;
|
||||
i32 sys_pipe2(i32[hasatleast 2], u32) _Hide;
|
||||
i32 sys_pivot_root(const char *, const char *) _Hide;
|
||||
i32 sys_pledge(const char *, const char *) _Hide;
|
||||
i32 sys_posix_openpt(i32) _Hide;
|
||||
i32 sys_renameat(i32, const char *, i32, const char *) _Hide;
|
||||
i32 sys_sem_close(i64) _Hide;
|
||||
i32 sys_sem_destroy(i64) _Hide;
|
||||
i32 sys_sem_getvalue(i64, u32 *) _Hide;
|
||||
i32 sys_sem_init(u32, i64 *) _Hide;
|
||||
i32 sys_sem_open(const char *, int, u32, i64 *) _Hide;
|
||||
i32 sys_sem_post(i64) _Hide;
|
||||
i32 sys_sem_trywait(i64) _Hide;
|
||||
i32 sys_sem_unlink(const char *) _Hide;
|
||||
i32 sys_sem_wait(i64) _Hide;
|
||||
i32 sys_setfsgid(i32) _Hide;
|
||||
i32 sys_setfsuid(i32) _Hide;
|
||||
i32 sys_setgid(i32) _Hide;
|
||||
i32 sys_setpgid(i32, i32) _Hide;
|
||||
i32 sys_setpriority(i32, u32, i32) _Hide;
|
||||
i32 sys_setregid(u32, u32) _Hide;
|
||||
i32 sys_setresgid(u32, u32, u32) _Hide;
|
||||
i32 sys_setresuid(u32, u32, u32) _Hide;
|
||||
i32 sys_setreuid(u32, u32) _Hide;
|
||||
i32 sys_setsid(void) _Hide;
|
||||
i32 sys_setuid(i32) _Hide;
|
||||
i32 sys_shm_open(const char *, i32, u32) _Hide;
|
||||
i32 sys_sigaction(i32, const void *, void *, i64, i64) _Hide;
|
||||
i32 sys_sigaltstack(const void *, void *) _Hide;
|
||||
i32 sys_symlinkat(const char *, i32, const char *) _Hide;
|
||||
i32 sys_sync(void) _Hide;
|
||||
i32 sys_sync_file_range(i32, i64, i64, u32) _Hide;
|
||||
i32 sys_syslog(i32, char *, i32) _Hide;
|
||||
i32 sys_tgkill(i32, i32, i32) _Hide;
|
||||
i32 sys_tkill(i32, i32, void *) _Hide;
|
||||
i32 sys_truncate(const char *, u64, u64) _Hide;
|
||||
i32 sys_uname(void *) _Hide;
|
||||
i32 sys_unlink(const char *) _Hide;
|
||||
i32 sys_unlinkat(i32, const char *, i32) _Hide;
|
||||
i32 sys_unmount(const char *, i32) _Hide;
|
||||
i32 sys_unveil(const char *, const char *) _Hide;
|
||||
i64 __sys_ptrace(i32, i32, i64, long *) _Hide;
|
||||
i64 sys_copy_file_range(i32, long *, i32, long *, u64, u32) _Hide;
|
||||
i64 sys_getrandom(void *, u64, u32) _Hide;
|
||||
i64 sys_lseek(i32, i64, i64, i64) _Hide;
|
||||
i64 sys_pread(i32, void *, u64, i64, i64) _Hide;
|
||||
i64 sys_pwrite(i32, const void *, u64, i64, i64) _Hide;
|
||||
i64 sys_read(i32, void *, u64) _Hide;
|
||||
i64 sys_readlink(const char *, char *, u64) _Hide;
|
||||
i64 sys_readlinkat(i32, const char *, char *, u64) _Hide;
|
||||
i64 sys_sendfile(i32, i32, i64 *, u64) _Hide;
|
||||
i64 sys_splice(i32, i64 *, i32, i64 *, u64, u32) _Hide;
|
||||
i64 sys_write(i32, const void *, u64) _Hide;
|
||||
u32 sys_getegid(void) _Hide;
|
||||
u32 sys_geteuid(void) _Hide;
|
||||
u32 sys_getgid(void) _Hide;
|
||||
u32 sys_getuid(void) _Hide;
|
||||
u32 sys_umask(u32) _Hide;
|
||||
void *__sys_mmap(void *, u64, u32, u32, i64, i64, i64) _Hide;
|
||||
void *sys_mremap(void *, u64, u64, i32, void *) _Hide;
|
||||
void sys_exit(i32) _Hide;
|
||||
|
||||
#undef i32
|
||||
#undef i64
|
||||
|
||||
@@ -3,25 +3,25 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
bool isdirectory_nt(const char *) hidden;
|
||||
bool isregularfile_nt(const char *) hidden;
|
||||
bool issymlink_nt(const char *) hidden;
|
||||
bool32 ntsetprivilege(int64_t, const char16_t *, uint32_t) hidden;
|
||||
char16_t *CreatePipeName(char16_t *) hidden;
|
||||
int __mkntpath(const char *, char16_t[hasatleast PATH_MAX]) hidden;
|
||||
int __mkntpath2(const char *, char16_t[hasatleast PATH_MAX], int) hidden;
|
||||
int __mkntpathat(int, const char *, int, char16_t[hasatleast PATH_MAX]) hidden;
|
||||
int __sample_pids(int[hasatleast 64], int64_t[hasatleast 64], bool) hidden;
|
||||
int ntaccesscheck(const char16_t *, uint32_t) paramsnonnull() hidden;
|
||||
int sys_pause_nt(void) hidden;
|
||||
int64_t __fix_enotdir(int64_t, char16_t *) hidden;
|
||||
int64_t __fix_enotdir3(int64_t, char16_t *, char16_t *) hidden;
|
||||
bool isdirectory_nt(const char *) _Hide;
|
||||
bool isregularfile_nt(const char *) _Hide;
|
||||
bool issymlink_nt(const char *) _Hide;
|
||||
bool32 ntsetprivilege(int64_t, const char16_t *, uint32_t) _Hide;
|
||||
char16_t *CreatePipeName(char16_t *) _Hide;
|
||||
int __mkntpath(const char *, char16_t[hasatleast PATH_MAX]) _Hide;
|
||||
int __mkntpath2(const char *, char16_t[hasatleast PATH_MAX], int) _Hide;
|
||||
int __mkntpathat(int, const char *, int, char16_t[hasatleast PATH_MAX]) _Hide;
|
||||
int __sample_pids(int[hasatleast 64], int64_t[hasatleast 64], bool) _Hide;
|
||||
int ntaccesscheck(const char16_t *, uint32_t) paramsnonnull() _Hide;
|
||||
int sys_pause_nt(void) _Hide;
|
||||
int64_t __fix_enotdir(int64_t, char16_t *) _Hide;
|
||||
int64_t __fix_enotdir3(int64_t, char16_t *, char16_t *) _Hide;
|
||||
int64_t __winerr(void) nocallback privileged;
|
||||
int64_t ntreturn(uint32_t);
|
||||
void *GetProcAddressModule(const char *, const char *) hidden;
|
||||
void WinMainForked(void) hidden;
|
||||
void _check_sigalrm(void) hidden;
|
||||
void _check_sigchld(void) hidden;
|
||||
void *GetProcAddressModule(const char *, const char *) _Hide;
|
||||
void WinMainForked(void) _Hide;
|
||||
void _check_sigalrm(void) _Hide;
|
||||
void _check_sigchld(void) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -6,27 +6,27 @@ COSMOPOLITAN_C_START_
|
||||
│ cosmopolitan § syscalls » system five » structless support ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
bool __is_linux_2_6_23(void) hidden;
|
||||
bool __is_linux_2_6_23(void) _Hide;
|
||||
bool32 sys_isatty_metal(int);
|
||||
int __fixupnewfd(int, int) hidden;
|
||||
int __fixupnewfd(int, int) _Hide;
|
||||
int __notziposat(int, const char *);
|
||||
int __tkill(int, int, void *) hidden;
|
||||
int _fork(uint32_t) hidden;
|
||||
int _isptmaster(int) hidden;
|
||||
int _ptsname(int, char *, size_t) hidden;
|
||||
int getdomainname_linux(char *, size_t) hidden;
|
||||
int gethostname_bsd(char *, size_t, int) hidden;
|
||||
int gethostname_linux(char *, size_t) hidden;
|
||||
int gethostname_nt(char *, size_t, int) hidden;
|
||||
int __tkill(int, int, void *) _Hide;
|
||||
int _fork(uint32_t) _Hide;
|
||||
int _isptmaster(int) _Hide;
|
||||
int _ptsname(int, char *, size_t) _Hide;
|
||||
int getdomainname_linux(char *, size_t) _Hide;
|
||||
int gethostname_bsd(char *, size_t, int) _Hide;
|
||||
int gethostname_linux(char *, size_t) _Hide;
|
||||
int gethostname_nt(char *, size_t, int) _Hide;
|
||||
int sys_msyscall(void *, size_t);
|
||||
long sys_bogus(void);
|
||||
ssize_t __getrandom(void *, size_t, unsigned) hidden;
|
||||
void *__vdsosym(const char *, const char *) hidden;
|
||||
void __onfork(void) hidden;
|
||||
void __restore_rt() hidden;
|
||||
void __restore_rt_netbsd(void) hidden;
|
||||
void cosmo2flock(uintptr_t) hidden;
|
||||
void flock2cosmo(uintptr_t) hidden;
|
||||
ssize_t __getrandom(void *, size_t, unsigned) _Hide;
|
||||
void *__vdsosym(const char *, const char *) _Hide;
|
||||
void __onfork(void) _Hide;
|
||||
void __restore_rt() _Hide;
|
||||
void __restore_rt_netbsd(void) _Hide;
|
||||
void cosmo2flock(uintptr_t) _Hide;
|
||||
void flock2cosmo(uintptr_t) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "libc/calls/struct/sysinfo.internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/calls/struct/vmmeter-meta.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
@@ -32,7 +31,7 @@
|
||||
#define CTL_KERN 1
|
||||
#define CTL_HW 6
|
||||
#define KERN_BOOTTIME 21
|
||||
#define HW_PHYSMEM 5
|
||||
#define HW_PHYSMEM (IsXnu() ? 24 : 5)
|
||||
|
||||
static int64_t GetUptime(void) {
|
||||
if (IsNetbsd()) return 0; // TODO(jart): Why?
|
||||
@@ -44,7 +43,7 @@ static int64_t GetUptime(void) {
|
||||
}
|
||||
|
||||
static int64_t GetPhysmem(void) {
|
||||
uint64_t x;
|
||||
uint64_t x = 0;
|
||||
size_t n = sizeof(x);
|
||||
int mib[] = {CTL_HW, HW_PHYSMEM};
|
||||
if (sys_sysctl(mib, ARRAYLEN(mib), &x, &n, 0, 0) == -1) return 0;
|
||||
@@ -82,9 +81,6 @@ int sysinfo(struct sysinfo *info) {
|
||||
rc = sys_sysinfo_nt(&x);
|
||||
}
|
||||
if (rc != -1) {
|
||||
x.procs = MAX(1, x.procs);
|
||||
x.mem_unit = MAX(1, x.mem_unit);
|
||||
x.totalram = MAX((8 * 1024 * 1024) / x.mem_unit, x.totalram);
|
||||
memcpy(info, &x, sizeof(x));
|
||||
}
|
||||
STRACE("sysinfo(%p) → %d% m", info, rc);
|
||||
|
||||
@@ -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 2023 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/struct/winsize.h"
|
||||
|
||||
/**
|
||||
* Gets terminal window size.
|
||||
*/
|
||||
int tcgetwinsize(int fd, struct winsize *ws) {
|
||||
return ioctl_tiocgwinsz(fd, ws);
|
||||
}
|
||||
@@ -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 2023 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/struct/winsize.h"
|
||||
|
||||
/**
|
||||
* Sets terminal window size attributes.
|
||||
*/
|
||||
int tcsetwinsize(int fd, const struct winsize *ws) {
|
||||
return ioctl_tiocswinsz(fd, ws);
|
||||
}
|
||||
@@ -35,6 +35,8 @@ int cfsetospeed(struct termios *, unsigned);
|
||||
int cfsetispeed(struct termios *, unsigned);
|
||||
uint32_t cfgetospeed(const struct termios *);
|
||||
uint32_t cfgetispeed(const struct termios *);
|
||||
int tcsetwinsize(int, const struct winsize *);
|
||||
int tcgetwinsize(int, struct winsize *);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § teletypewriter » undiamonding ─╬─│┼
|
||||
|
||||
@@ -29,6 +29,6 @@
|
||||
*/
|
||||
struct timespec timespec_mono(void) {
|
||||
struct timespec ts;
|
||||
_npassert(!clock_gettime(CLOCK_MONOTONIC_FAST, &ts));
|
||||
_npassert(!clock_gettime(CLOCK_MONOTONIC, &ts));
|
||||
return ts;
|
||||
}
|
||||
@@ -31,6 +31,6 @@
|
||||
*/
|
||||
struct timespec timespec_real(void) {
|
||||
struct timespec ts;
|
||||
_npassert(!clock_gettime(CLOCK_REALTIME_FAST, &ts));
|
||||
_npassert(!clock_gettime(CLOCK_REALTIME, &ts));
|
||||
return ts;
|
||||
}
|
||||
Loaded 100 of 838 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user