mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-12 05:59:10 +00:00
Support Linux binfmt_misc and APE loading on Apple
The "no modify self" variant of Actually Portable Executable is now supported on all platforms. If you use `$(APE_NO_MODIFY_SELF)` then ld.bfd will embed a 4096 byte ELF binary and a 4096 byte Macho file which are installed on the fly to ${TMPDIR:-/tmp}, which enables us launch the executable, without needing to copy the whole executable To prevent it from copying a tiny executable to your temp directory you need to install the `ape` command (renamed from ape-loader), to a system path. For example: # FreeBSD / NetBSD / OpenBSD make -j8 o//ape/ape cp o//ape/ape /usr/bin/ape # Mac OS # make -j8 o//ape/ape.macho curl https://justine.lol/ape.macho >/usr/bin/ape chmod +x /usr/bin/ape On Linux you can get even more performance with the new binfmt_misc support which makes launching non-modifying APE binaries as fast as launching ELF executables. Running the following command: # Linux ape/apeinstall.sh Will copy APE loader to /usr/bin/ape and register with binfmt_misc Lastly, this change also fixes a really interesting race condition with OpenBSD thread joining.
This commit is contained in:
parent
7838edae88
commit
db0d8dd806
31 changed files with 1089 additions and 305 deletions
39
ape/ape.S
39
ape/ape.S
|
@ -542,27 +542,35 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang
|
|||
// present two choices.
|
||||
.ascii "o=\"$(command -v \"$0\")\"\n"
|
||||
// Try to use a system-wide APE loader.
|
||||
.ascii "type ape-loader >/dev/null 2>&1 && "
|
||||
.ascii "exec ape-loader \"$o\" \"$@\"\n"
|
||||
.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 "if [ ! -d /Applications ]; then\n"
|
||||
.ascii "t=\"${TMPDIR:-/tmp}/ape-loader\"\n"
|
||||
.ascii "[ -x \"$t\" ] || {\n"
|
||||
.ascii "t=\"${TMPDIR:-/tmp}/ape\"\n"
|
||||
.ascii "if [ ! -x \"$t\" ]; then\n"
|
||||
.ascii "if [ ! -d /Applications ]; then\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 "chmod 755 \"$t.$$\" &&\n"
|
||||
.ascii "mv \"$t.$$\" \"$t\"\n"
|
||||
.ascii "}\n"
|
||||
.ascii "exec \"$t\" \"$o\" \"$@\"\n"
|
||||
.ascii "\" bs=64\n"
|
||||
#if SupportsXnu() && defined(APE_LOADER_MACHO)
|
||||
.ascii "else\n"
|
||||
.ascii "dd if=\"$o\" of=\"$t.$$\" skip=\""
|
||||
.shstub ape_loader_macho_dd_skip,2
|
||||
.ascii "\" count=\""
|
||||
.shstub ape_loader_macho_dd_count,2
|
||||
.ascii "\" bs=64\n"
|
||||
#endif /* APE_LOADER_MACHO */
|
||||
.ascii "fi 2>/dev/null &&\n"
|
||||
.ascii "chmod 755 \"$t.$$\" &&\n"
|
||||
.ascii "mv \"$t.$$\" \"$t\"\n"
|
||||
.ascii "fi\n"
|
||||
#endif
|
||||
.ascii "exec \"$t\" \"$o\" \"$@\"\n"
|
||||
#endif /* APE_LOADER */
|
||||
#ifndef APE_NO_MODIFY_SELF
|
||||
// The default behavior is: to overwrite the header in place.
|
||||
// We prefer this because it's a tiny constant one time cost.
|
||||
|
@ -656,6 +664,11 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang
|
|||
.incbin APE_LOADER
|
||||
.previous
|
||||
#endif /* APE_LOADER */
|
||||
#if SupportsXnu() && defined(APE_LOADER_MACHO)
|
||||
.section .ape.loader-macho,"a",@progbits
|
||||
.incbin APE_LOADER_MACHO
|
||||
.previous
|
||||
#endif /* APE_LOADER_MACHO */
|
||||
#endif /* SupportsWindows() || SupportsMetal() || SupportsXnu() */
|
||||
|
||||
#if SupportsSystemv() || SupportsMetal()
|
||||
|
@ -856,7 +869,7 @@ ape_macho:
|
|||
.long (520f-510f)/4 # count
|
||||
510: .quad 0 # rax
|
||||
.quad IMAGE_BASE_VIRTUAL # rbx
|
||||
.quad 0 # rcx
|
||||
.quad XNU # rcx
|
||||
.quad 0 # rdx
|
||||
.quad 0 # rdi
|
||||
.quad 0 # rsi
|
||||
|
@ -870,7 +883,7 @@ ape_macho:
|
|||
.quad 0 # r13
|
||||
.quad 0 # r14
|
||||
.quad 0 # r15
|
||||
.quad _xnu # rip
|
||||
.quad _start # rip
|
||||
.quad 0 # rflags
|
||||
.quad 0 # cs
|
||||
.quad 0 # fs
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue