Make blink support conditionally linkable into APE

This commit is contained in:
Justine Tunney 2023-06-17 07:55:35 -07:00
parent 52d28966f7
commit 562a1384cd
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
21 changed files with 288 additions and 269 deletions

260
ape/ape.S
View file

@ -598,40 +598,40 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
// modify the binary to follow the local system's convention.
// There isn't a one-size-fits-all approach for this, thus we
// present two choices.
.ascii "o=\"$(command -v \"$0\")\"\n"
.ascii "o=\"$(command -v \"$0\")\"\n"
// Try to use a system-wide APE loader.
.ascii "[ x\"$1\" != x--assimilate ] && "
.ascii "type ape >/dev/null 2>&1 && "
.ascii "exec ape \"$o\" \"$@\"\n"
.ascii "[ x\"$1\" != x--assimilate ] && "
.ascii "type ape >/dev/null 2>&1 && "
.ascii "exec ape \"$o\" \"$@\"\n"
#ifdef APE_LOADER
// There is no system-wide APE loader, but there is one
// embedded inside the APE. So if the system is not MacOs,
// extract the loader into a temp folder, and use it to
// load the APE without modifying it.
.ascii "[ x\"$1\" != x--assimilate ] && {\n"
.ascii "t=\"${TMPDIR:-${HOME:-.}}/.ape\"\n"
.ascii "[ -x \"$t\" ] || {\n"
.ascii "mkdir -p \"${t%/*}\" &&\n"
.ascii "dd if=\"$o\" of=\"$t.$$\" skip="
.shstub ape_loader_dd_skip,2
.ascii " count="
.shstub ape_loader_dd_count,2
.ascii " bs=64 2>/dev/null\n"
.ascii "[ x\"$1\" != x--assimilate ] && {\n"
.ascii "t=\"${TMPDIR:-${HOME:-.}}/.ape\"\n"
.ascii "[ -x \"$t\" ] || {\n"
.ascii "mkdir -p \"${t%/*}\" &&\n"
.ascii "dd if=\"$o\" of=\"$t.$$\" skip="
.shstub ape_loader_dd_skip,2
.ascii " count="
.shstub ape_loader_dd_count,2
.ascii " bs=64 2>/dev/null\n"
#if SupportsXnu()
.ascii "[ -d /Applications ] && "
.ascii "dd if=\"$t.$$\""
.ascii " of=\"$t.$$\""
.ascii " skip=6"
.ascii " count=10"
.ascii " bs=64"
.ascii " conv=notrunc"
.ascii " 2>/dev/null\n"
.ascii "[ -d /Applications ] && "
.ascii "dd if=\"$t.$$\""
.ascii " of=\"$t.$$\""
.ascii " skip=6"
.ascii " count=10"
.ascii " bs=64"
.ascii " conv=notrunc"
.ascii " 2>/dev/null\n"
#endif /* SupportsXnu() */
.ascii "chmod 755 \"$t.$$\"\n"
.ascii "mv -f \"$t.$$\" \"$t\"\n"
.ascii "chmod 755 \"$t.$$\"\n"
.ascii "mv -f \"$t.$$\" \"$t\"\n"
.ascii "}\n"
.ascii "exec \"$t\" \"$o\" \"$@\"\n"
.ascii "}\n"
.ascii "exec \"$t\" \"$o\" \"$@\"\n"
.ascii "}\n"
#endif /* APE_LOADER */
#ifndef APE_NO_MODIFY_SELF
// The default behavior is: to overwrite the header in place.
@ -641,155 +641,91 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
// The alternative behavior is to copy to $TMPDIR or $HOME or
// the current directory. We like TMPDIR because it's part of
// the IEEE POSIX standard whereas alternatives (XDG) aren't.
.ascii "t=\"${TMPDIR:-${HOME:-.}}/$0\"\n"
.ascii "[ x\"$1\" != x--assimilate ] || [ ! -e \"$t\" ] && {\n"
.ascii "[ x\"$1\" != x--assimilate ] && {\n"
.ascii "mkdir -p \"${t%/*}\" 2>/dev/null\n"
.ascii "cp -f \"$o\" \"$t.$$\" &&\n"
.ascii "mv -f \"$t.$$\" \"$t\" || exit 120\n"
.ascii "o=\"$t\"\n"
.ascii "}\n"
.ascii "t=\"${TMPDIR:-${HOME:-.}}/$0\"\n"
.ascii "[ x\"$1\" != x--assimilate ] || [ ! -e \"$t\" ] && {\n"
.ascii "[ x\"$1\" != x--assimilate ] && {\n"
.ascii "mkdir -p \"${t%/*}\" 2>/dev/null\n"
.ascii "cp -f \"$o\" \"$t.$$\" &&\n"
.ascii "mv -f \"$t.$$\" \"$t\" || exit 120\n"
.ascii "o=\"$t\"\n"
.ascii "}\n"
#endif /* APE_NO_MODIFY_SELF */
.ascii "exec 7<> \"$o\" || exit 121\n"
.ascii "printf '"
.ascii "\\177ELF" // 0x0: ELF
.ascii "\\2" // 4: long mode
.ascii "\\1" // 5: little endian
.ascii "\\1" // 6: elf v1.o
.ascii "\\011" // 7: FreeBSD
.ascii "\\0" // 8: os/abi ver.
.ascii "\\0\\0\\0" // 9: padding 3/7
.ascii "\\0\\0\\0\\0" // padding 4/7
.ascii "\\2\\0" // 10: εxεcµταblε
.ascii "\\076\\0" // 12: NexGen32e
.ascii "\\1\\0\\0\\0" // 14: elf v1.o
.shstub ape_elf_entry,8 // 18: e_entry
.shstub ape_elf_phoff,8 // 20: e_phoff
.shstub ape_elf_shoff,8 // 28: e_shoff
.ascii "\\0\\0\\0\\0" // 30: e_flags
.ascii "\\100\\0" // 34: e_ehsize
.ascii "\\070\\0" // 36: e_phentsize
.shstub ape_elf_phnum,2 // 38: e_phnum
.ascii "\\0\\0" // 3a: e_shentsize
.shstub ape_elf_shnum,2 // 3c: e_shnum
.shstub ape_elf_shstrndx,2 // 3e: e_shstrndx
.ascii "' >&7\n"
.ascii "exec 7<&-\n"
.ascii "exec 7<> \"$o\" || exit 121\n"
.ascii "printf '"
.ascii "\\177ELF" // 0x0: ELF
.ascii "\\2" // 4: long mode
.ascii "\\1" // 5: little endian
.ascii "\\1" // 6: elf v1.o
.ascii "\\011" // 7: FreeBSD
.ascii "\\0" // 8: os/abi ver.
.ascii "\\0\\0\\0" // 9: padding 3/7
.ascii "\\0\\0\\0\\0" // padding 4/7
.ascii "\\2\\0" // 10: εxεcµταblε
.ascii "\\076\\0" // 12: NexGen32e
.ascii "\\1\\0\\0\\0" // 14: elf v1.o
.shstub ape_elf_entry,8 // 18: e_entry
.shstub ape_elf_phoff,8 // 20: e_phoff
.shstub ape_elf_shoff,8 // 28: e_shoff
.ascii "\\0\\0\\0\\0" // 30: e_flags
.ascii "\\100\\0" // 34: e_ehsize
.ascii "\\070\\0" // 36: e_phentsize
.shstub ape_elf_phnum,2 // 38: e_phnum
.ascii "\\0\\0" // 3a: e_shentsize
.shstub ape_elf_shnum,2 // 3c: e_shnum
.shstub ape_elf_shstrndx,2 // 3e: e_shstrndx
.ascii "' >&7\n"
.ascii "exec 7<&-\n"
#if SupportsXnu()
.ascii "[ -d /Applications ] && "
.ascii "dd if=\"$o\""
.ascii " of=\"$o\""
.ascii " bs=8"
.ascii " skip="
.shstub ape_macho_dd_skip,2
.ascii " count="
.shstub ape_macho_dd_count,2
.ascii " conv=notrunc 2>/dev/null\n"
.ascii "[ -d /Applications ] && "
.ascii "dd if=\"$o\""
.ascii " of=\"$o\""
.ascii " bs=8"
.ascii " skip="
.shstub ape_macho_dd_skip,2
.ascii " count="
.shstub ape_macho_dd_count,2
.ascii " conv=notrunc 2>/dev/null\n"
#endif /* XNU */
.ascii "[ x\"$1\" = x--assimilate ] && exit 0\n"
.ascii "[ x\"$1\" = x--assimilate ] && exit 0\n"
#ifndef APE_NO_MODIFY_SELF
.ascii "exec \"$0\" \"$@\"\n" // try to preserve argv[0]
.ascii "exec \"$0\" \"$@\"\n" // try to preserve argv[0]
#else
.ascii "}\n"
.ascii "o=\"$t\"\n"
.ascii "exec \"$o\" \"$@\"\n"
.ascii "}\n"
.ascii "o=\"$t\"\n"
.ascii "exec \"$o\" \"$@\"\n"
#endif /* APE_NO_MODIFY_SELF */
.ascii "exit $?\n"
.ascii "fi\n"
.ascii "exit $?\n"
.ascii "fi\n" // x86_64
// ...
// decentralized section (.apesh)
// ...
.ascii "PHDRS='' <<'@'\n"
.endobj apesh
#if !IsTiny()
// elf program headers get inserted here
// because they need to be in the first 4096 bytes
.section .emush,"a",@progbits
.section .emushprologue,"a",@progbits
emush: .ascii "\n@\n#'\"\n"
.ascii "s=\"$(uname -s)\"\n"
// our script is running on a non-x86_64 architecture
// 1. `dd` out the appropriate blink vm blob
// 2. gunzip the blink virtual machine executable
// 3. relaunch this program inside the blink vm
.ascii "o=\"$(command -v \"$0\")\"\n"
.ascii "e=\"${TMPDIR:-${HOME:-.}}/.ape-blink-1.0.0\"\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"
.previous
// ...
// decentralized section (.emush)
// - STATIC_YOINK("blink_linux_aarch64"); // for raspberry pi
// - STATIC_YOINK("blink_xnu_aarch64"); // is apple silicon
// ...
.section .emushepilogue,"a",@progbits
.ascii "echo \"$0: this ape binary lacks $m support\" >&2\n"
.rept 16
.ascii "exit 127\n"
.endr
.ascii "exit 1\n"
.endobj emush
#endif /* !IsTiny() */
.previous
#ifdef APE_LOADER
.section .ape.loader,"a",@progbits
@ -1941,27 +1877,5 @@ __bss_start:
__bss_end:
.previous
#if !IsTiny()
#ifdef APE_IS_SHELL_SCRIPT
.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
#endif /* APE_IS_SHELL_SCRIPT */
#endif /* !IsTiny() */
.end


View file

@ -226,7 +226,6 @@ SECTIONS {
/* Real Mode */
KEEP(*(.head))
KEEP(*(.apesh))
KEEP(*(.head2))
KEEP(*(.text.head))
/* Executable & Linkable Format */
@ -235,7 +234,9 @@ SECTIONS {
KEEP(*(.elf.phdrs))
HIDDEN(ape_phdrs_end = .);
KEEP(*(.emushprologue))
KEEP(*(.emush))
KEEP(*(.emushepilogue))
/* OpenBSD */
. = ALIGN(__SIZEOF_POINTER__);
@ -597,49 +598,24 @@ SHSTUB2(ape_loader_dd_count,
#if defined(APE_IS_SHELL_SCRIPT) && !IsTiny()
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);
#define IDENTITY(X) X
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);
#define APE_DECLARE_FIXED_DECIMAL(F, X) \
HIDDEN(X##_quad = DEFINED(X) ? ((F(X) < 1000000000 ? 32 : F(X) / 1000000000 % 10 + 48) << 000 | \
(F(X) < 100000000 ? 32 : F(X) / 100000000 % 10 + 48) << 010 | \
(F(X) < 10000000 ? 32 : F(X) / 10000000 % 10 + 48) << 020 | \
(F(X) < 1000000 ? 32 : F(X) / 1000000 % 10 + 48) << 030 | \
(F(X) < 100000 ? 32 : F(X) / 100000 % 10 + 48) << 040 | \
(F(X) < 10000 ? 32 : F(X) / 10000 % 10 + 48) << 050 | \
(F(X) < 1000 ? 32 : F(X) / 1000 % 10 + 48) << 060 | \
(F(X) < 100 ? 32 : F(X) / 100 % 10 + 48) << 070) : 0); \
HIDDEN(X##_short = DEFINED(X) ? ((F(X) < 10 ? 32 : F(X) / 10 % 10 + 48) << 000 | \
(F(X) % 10 + 48) << 010) : 0)
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);
APE_DECLARE_FIXED_DECIMAL(RVA, blink_linux_aarch64);
APE_DECLARE_FIXED_DECIMAL(IDENTITY, blink_linux_aarch64_size);
APE_DECLARE_FIXED_DECIMAL(RVA, blink_xnu_aarch64);
APE_DECLARE_FIXED_DECIMAL(IDENTITY, blink_xnu_aarch64_size);
#endif /* APE_IS_SHELL_SCRIPT */

View file

@ -141,8 +141,8 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
libc/runtime/mman.internal.h \
libc/runtime/pc.internal.h \
libc/sysv/consts/prot.h \
ape/blink-aarch64.gz \
ape/blink-darwin-arm64.gz \
ape/blink-linux-aarch64.gz \
ape/blink-xnu-aarch64.gz \
o/$(MODE)/ape/ape.elf
@$(COMPILE) \
-AOBJECTIFY.S \
@ -170,8 +170,8 @@ o/$(MODE)/ape/ape-copy-self.o: \
libc/runtime/mman.internal.h \
libc/runtime/pc.internal.h \
libc/sysv/consts/prot.h \
ape/blink-aarch64.gz \
ape/blink-darwin-arm64.gz
ape/blink-linux-aarch64.gz \
ape/blink-xnu-aarch64.gz
@$(COMPILE) \
-AOBJECTIFY.S \
$(OBJECTIFY.S) \
@ -232,8 +232,8 @@ o/$(MODE)/ape/ape.o: ape/ape.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/ape/ape.o: \
ape/blink-aarch64.gz \
ape/blink-darwin-arm64.gz
ape/blink-linux-aarch64.gz \
ape/blink-xnu-aarch64.gz
o/$(MODE)/ape/ape.lds: \
ape/ape.lds \

View file

@ -241,7 +241,7 @@ DEFAULT_LDFLAGS = \
-nostdlib \
--gc-sections \
--build-id=none \
--no-dynamic-linker #--cref -Map=$@.map
--no-dynamic-linker --cref -Map=$@.map
ifeq ($(ARCH), aarch64)
DEFAULT_LDFLAGS += \

View file

@ -25,8 +25,7 @@
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
extern const unsigned TIOCPTSNAME;
#define TIOCGPTN 0x80045430 // linux
#define TIOCPTYGNAME 0x40807453 // xnu
#define TIOCPTSNAME 0x48087448 // netbsd
#define FIODGNAME 0x80106678 // freebsd

View file

@ -25,7 +25,8 @@
#include "libc/sysv/consts/pty.h"
#include "libc/sysv/errfuns.h"
#define TIOCPTYUNLK 0x20007452
#define TIOCSPTLCK 0x40045431 // linux
#define TIOCPTYUNLK 0x20007452 // xnu
/**
* Unlocks pseudoteletypewriter pair.

View file

@ -17,8 +17,10 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/fmt/fmt.h"
#include "libc/intrin/kprintf.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/log/color.internal.h"
#include "libc/log/gdb.h"
@ -31,9 +33,11 @@
#include "libc/runtime/symbols.internal.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/w.h"
#include "libc/sysv/errfuns.h"
/**
* Launches GDB debugger GUI for current process.
@ -54,14 +58,18 @@
relegated int(AttachDebugger)(intptr_t continuetoaddr) {
int pid, ttyfd;
struct StackFrame *bp;
char pidstr[11], breakcmd[40];
char pidstr[12], breakcmd[40];
const char *se, *elf, *gdb, *rewind, *layout;
__restore_tty();
if (IsGenuineBlink() || !(gdb = GetGdbPath()) || !isatty(0) || !isatty(1) ||
(ttyfd = open(_PATH_TTY, O_RDWR | O_CLOEXEC)) == -1) {
return -1;
if (!IsLinux() || //
IsGenuineBlink() || //
!(gdb = GetGdbPath()) || //
!isatty(0) || //
!isatty(1) || //
(ttyfd = sys_openat(AT_FDCWD, _PATH_TTY, O_RDWR | O_CLOEXEC, 0)) == -1) {
return enosys();
}
ksnprintf(pidstr, sizeof(pidstr), "%u", getpid());
FormatUint32(pidstr, getpid());
layout = "layout asm";
if ((elf = FindDebugBinary())) {
se = "-se";
@ -76,29 +84,31 @@ relegated int(AttachDebugger)(intptr_t continuetoaddr) {
continuetoaddr = bp->addr;
}
rewind = "-ex";
ksnprintf(breakcmd, sizeof(breakcmd), "%s *%#p", "break", continuetoaddr);
FormatHex64(stpcpy(breakcmd, "break *"), continuetoaddr, 1);
} else {
rewind = NULL;
breakcmd[0] = '\0';
}
if (!(pid = fork())) {
dup2(ttyfd, 0);
dup2(ttyfd, 1);
execv(gdb, (char *const[]){
"gdb", "--tui",
"-p", pidstr,
se, elf,
"-ex", "set osabi GNU/Linux",
"-ex", "set complaints 0",
"-ex", "set confirm off",
"-ex", layout,
"-ex", "layout reg",
"-ex", "set var g_gdbsync = 1",
"-q", rewind,
breakcmd, "-ex",
"c", NULL,
});
abort();
sys_dup2(ttyfd, 0, 0);
sys_dup2(ttyfd, 1, 0);
__sys_execve(gdb,
(char *const[]){
"gdb", "--tui",
"-p", pidstr,
se, elf,
"-ex", "set osabi GNU/Linux",
"-ex", "set complaints 0",
"-ex", "set confirm off",
"-ex", layout,
"-ex", "layout reg",
"-ex", "set var g_gdbsync = 1",
"-q", rewind,
breakcmd, "-ex",
"c", NULL,
},
environ);
__builtin_trap();
}
return pid;
}

View file

@ -0,0 +1,60 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 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/macros.internal.h"
// Blink Virtual Machine for Linux Arm64
//
// If you want to support Raspberry Pi by embedding an emulator
// in your APE binary that runs automatically, then put this:
//
// STATIC_YOINK("blink_linux_aarch64");
//
// In your main.c file, to pull it into linkage from the static
// archive. Alternatively, you may simply add blink_linux_aarch64.o
// as an explicit linker argument.
.section .blink,"a",@progbits
.globl blink_linux_aarch64_size
blink_linux_aarch64:
.incbin "ape/blink-linux-aarch64.gz"
.endobj blink_linux_aarch64,globl
blink_linux_aarch64_size = . - blink_linux_aarch64
.section .emush,"a",@progbits
.ascii "if [ \"$s\" = Linux ]; then\n"
.ascii "if [ \"$m\" = aarch64 ] || [ \"$m\" = arm64 ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-linux-aarch64 to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.weak blink_linux_aarch64_quad
.quad blink_linux_aarch64_quad
.weak blink_linux_aarch64_short
.short blink_linux_aarch64_short
.ascii ")) count=$(("
.weak blink_linux_aarch64_size_quad
.quad blink_linux_aarch64_size_quad
.weak blink_linux_aarch64_size_short
.short blink_linux_aarch64_size_short
.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"

View file

@ -0,0 +1,58 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 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/macros.internal.h"
// Blink Virtual Machine for Apple Silicon
//
// If you want to support Apple M1 by embedding an emulator in
// your APE binary that runs automatically, then put this:
//
// STATIC_YOINK("blink_xnu_aarch64");
//
// In your main.c file, to pull it into linkage from the static
// archive. Alternatively, you may simply add blink_xnu_aarch64.o
// as an explicit linker argument.
.section .blink,"a",@progbits
.globl blink_xnu_aarch64_size
blink_xnu_aarch64:
.incbin "ape/blink-xnu-aarch64.gz"
.endobj blink_xnu_aarch64,globl
blink_xnu_aarch64_size = . - blink_xnu_aarch64
.section .emush,"a",@progbits
.ascii "if [ \"$s\" = Darwin ] && [ \"$m\" = arm64 ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-darwin-aarch64 to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.weak blink_xnu_aarch64_quad
.quad blink_xnu_aarch64_quad
.weak blink_xnu_aarch64_short
.short blink_xnu_aarch64_short
.ascii ")) count=$(("
.weak blink_xnu_aarch64_size_quad
.quad blink_xnu_aarch64_size_quad
.weak blink_xnu_aarch64_size_short
.short blink_xnu_aarch64_size_short
.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"

View file

@ -88,6 +88,10 @@ o/$(MODE)/libc/nexgen32e/gclongjmp.o: libc/nexgen32e/gclongjmp.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/nexgen32e/checkstackalign.o: libc/nexgen32e/checkstackalign.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/nexgen32e/blink_xnu_aarch64.o: libc/nexgen32e/blink_xnu_aarch64.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/nexgen32e/blink_linux_aarch64.o: libc/nexgen32e/blink_linux_aarch64.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
LIBC_NEXGEN32E_LIBS = $(foreach x,$(LIBC_NEXGEN32E_ARTIFACTS),$($(x)))
LIBC_NEXGEN32E_SRCS = $(foreach x,$(LIBC_NEXGEN32E_ARTIFACTS),$($(x)_SRCS))

View file

@ -1451,8 +1451,6 @@ syscon termios CSTOP 19 19 19 19 19 19 19 0 # unix consensus
# Pseudoteletypewriter Control
#
# group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary
syscon pty TIOCGPTN 0x80045430 0x80045430 0 0 0x4004740f 0 0 0 # boop
syscon pty TIOCSPTLCK 0x40045431 0x40045431 0 0 0 0 0 0 # boop
syscon pty TIOCPKT 0x5420 0x5420 0x80047470 0x80047470 0x80047470 0x80047470 0x80047470 -1 # boop
syscon pty TIOCPKT_DATA 0 0 0 0 0 0 0 0 # consensus
syscon pty TIOCPKT_FLUSHREAD 1 1 1 1 1 1 1 1 # unix consensus

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon pty,TIOCGPTN,0x80045430,0x80045430,0,0,0x4004740f,0,0,0

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon pty,TIOCSPTLCK,0x40045431,0x40045431,0,0,0,0,0,0

View file

@ -12,7 +12,6 @@ extern const int TIOCPKT_IOCTL;
extern const int TIOCPKT_NOSTOP;
extern const int TIOCPKT_START;
extern const int TIOCPKT_STOP;
extern const int TIOCSPTLCK;
#define TIOCPKT_DATA 0x00
#define TIOCPKT_DOSTOP 0x01
@ -23,11 +22,9 @@ extern const int TIOCSPTLCK;
#define TIOCPKT_START 0x20
#define TIOCPKT_STOP 0x40
#define TIOCPKT TIOCPKT
#define TIOCSPTLCK TIOCSPTLCK
#define TIOCPKT TIOCPKT
#define __tmpcosmo_TIOCPKT -1036987649
#define __tmpcosmo_TIOCSPTLCK 372918192
#define __tmpcosmo_TIOCPKT -1036987649
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -81,7 +81,6 @@ extern const int TCSAFLUSH;
extern const int TCSANOW;
extern const uint64_t TIOCCONS;
extern const uint64_t TIOCGETD;
extern const uint64_t TIOCGPTN;
extern const uint64_t TIOCGWINSZ;
extern const uint64_t TIOCNOTTY;
extern const uint64_t TIOCNXCL;
@ -211,7 +210,6 @@ extern const uint32_t CRTSCTS;
#define TCSANOW 0
#define TIOCCONS TIOCCONS
#define TIOCGETD TIOCGETD
#define TIOCGPTN TIOCGPTN
#define TIOCGWINSZ TIOCGWINSZ
#define TIOCNOTTY TIOCNOTTY
#define TIOCNXCL TIOCNXCL
@ -308,7 +306,6 @@ extern const uint32_t CRTSCTS;
#define __tmpcosmo_TCOFLUSH 659539281
#define __tmpcosmo_TIOCCONS 1455144588
#define __tmpcosmo_TIOCGETD 470897144
#define __tmpcosmo_TIOCGPTN 67701595
#define __tmpcosmo_TIOCGWINSZ 965491756
#define __tmpcosmo_TIOCNOTTY 1073131930
#define __tmpcosmo_TIOCNXCL 1210582499

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/kprintf.h"
#include "libc/stdio/stdio.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
@ -38,7 +39,7 @@ double __testlib_ezbenchcontrol(void) {
if (Tries == 10) {
fputs("warning: failed to accurately benchmark control\n", stderr);
}
fprintf(stderr, "will subtract benchmark overhead of %g cycles\n\n",
kprintf("will subtract benchmark overhead of %g cycles\n\n",
g_ezbenchcontrol);
once = true;
}

View file

@ -16,12 +16,13 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/kprintf.h"
#include "libc/stdio/stdio.h"
#include "libc/testlib/testlib.h"
void testlib_incrementfailed(void) {
if (++g_testlib_failed > 23) {
fprintf(stderr, "too many failures, aborting\n");
kprintf("too many failures, aborting\n");
testlib_abort();
}
}

View file

@ -27,6 +27,7 @@
#include "libc/fmt/fmt.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/log/check.h"
@ -55,8 +56,7 @@ static pthread_mutex_t testlib_error_lock;
void testlib_finish(void) {
if (g_testlib_failed) {
fprintf(stderr, "%u / %u %s\n", g_testlib_failed, g_testlib_ran,
"tests failed");
kprintf("%u / %u %s\n", g_testlib_failed, g_testlib_ran, "tests failed");
}
}
@ -163,7 +163,7 @@ static void CheckForFileDescriptors(void) {
for (i = 0; i < ARRAYLEN(pfds); ++i) {
if (pfds[i].revents & POLLNVAL) continue;
++g_testlib_failed;
fprintf(stderr, "error: test failed to close() fd %d\n", pfds[i].fd);
kprintf("error: test failed to close() fd %d\n", pfds[i].fd);
}
}
#endif
@ -182,7 +182,7 @@ static void CheckForZombies(void) {
break;
} else {
++g_testlib_failed;
fprintf(stderr, "error: test failed to reap zombies %d\n", pid);
kprintf("error: test failed to reap zombies %d\n", pid);
}
}
#endif

View file

@ -139,7 +139,14 @@
#include "tool/net/sandbox.h"
STATIC_STACK_SIZE(0x40000);
STATIC_YOINK("zipos");
#ifndef TINY
STATIC_YOINK("blink_linux_aarch64"); // for raspberry pi
STATIC_YOINK("blink_xnu_aarch64"); // is apple silicon
#endif
#if !IsTiny()
#ifdef __x86_64__
STATIC_YOINK("ShowCrashReportsEarly");