mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-25 07:19:02 +00:00
Provide option to have APE not modify itself
This change introduces ape-no-modify-self.o to the amalgamated release binaries, which may be used as an alternative to ape.o to make it easier to use APE in cases where the self-modifying behavior isn't acceptable. Please note that this alternative copying behavior isn't necessarily better. It introduces a whole bunch of questions of its own, which are documented in the ape.S source comment and should be considered by both the program author as well as the end-user of programs linked this way. For example, build environments that use read-only file systems and would prefer to not have a launcher wrapper (like we use in our build) can use ape-no-modify-self.o instead of ape.o and then set the $TMPDIR environment variable to point to a sane read-write-exec location. Fixes #146 See #82
This commit is contained in:
parent
59575f7e80
commit
da8a08fd58
3 changed files with 77 additions and 6 deletions
49
ape/ape.S
49
ape/ape.S
|
@ -535,7 +535,37 @@ ape_disk:
|
|||
|
||||
#if SupportsWindows() || SupportsMetal() || SupportsXnu()
|
||||
apesh: .ascii "'\n#'\"\n" # sixth edition shebang
|
||||
// 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.
|
||||
// There isn't a one-size-fits-all approach for this, thus we
|
||||
// present two choices.
|
||||
#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.
|
||||
// We simply printf a 64-byte header and call execve() again.
|
||||
.ascii "o=\"$(command -v \"$0\")\"\n"
|
||||
#else
|
||||
// The alternative behavior is to copy to $TMPDIR and edit.
|
||||
// This imposes a variety of caveats of its own that should
|
||||
// be considered by the user beforehand, such as whether or
|
||||
// not /tmp is considered trustworthy on a given system, or
|
||||
// if the administrator chose to mount it with noexec. It's
|
||||
// up to the user to decide what's best in those situations
|
||||
// and also note that argv[0] and getauxval(AT_EXECFN) will
|
||||
// change as a result of this, and lastly note we don't try
|
||||
// to cleanup the tmp copies for the sake of efficiency. It
|
||||
// should also be noted that if $0 has directory components
|
||||
// then permission clashes can happen between system users,
|
||||
// since only root is able to set the sticky bit, which can
|
||||
// be addressed simply by overriding the TMPDIR environment
|
||||
.ascii "o=\"${TMPDIR:-/tmp}/$0\"\n"
|
||||
.ascii "if [ ! -e \"$o\" ]; then\n"
|
||||
.ascii "d=\"$o\"\n"
|
||||
.ascii "o=\"$o.$$\"\n"
|
||||
.ascii "mkdir -p \"${o%/*}\" 2>/dev/null\n"
|
||||
.ascii "cp -f \"$0\" \"$o\" || exit 120\n"
|
||||
#endif /* APE_NO_MODIFY_SELF */
|
||||
#if SupportsXnu()
|
||||
.ascii "if [ -d /Applications ]; then\n"
|
||||
.ascii "dd if=\"$o\""
|
||||
|
@ -547,7 +577,7 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang
|
|||
.shstub ape_macho_dd_count,2
|
||||
.ascii "\" conv=notrunc 2>/dev/null\n"
|
||||
.ascii "el"
|
||||
#endif
|
||||
#endif /* XNU */
|
||||
.ascii "if exec 7<> \"$o\"; then\n"
|
||||
.ascii "printf '"
|
||||
.ascii "\\177ELF" # 0x0: ⌂ELF
|
||||
|
@ -574,19 +604,28 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang
|
|||
.ascii "' >&7\n"
|
||||
.ascii "exec 7<&-\n"
|
||||
.ascii "else\n"
|
||||
.ascii "exit 1\n"
|
||||
.ascii "exit 121\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$0\" \"$@\"\n" # etxtbsy tail recursion
|
||||
.ascii "R=$?\n" # architecture optimistic
|
||||
#ifndef APE_NO_MODIFY_SELF
|
||||
.ascii "exec \"$0\" \"$@\"\n" # optimistic execution
|
||||
#else
|
||||
.ascii "mv -f \"$o\" \"$d\" 2>/dev/null\n"
|
||||
.ascii "o=\"$d\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$o\" \"$@\"\n"
|
||||
#endif /* APE_NO_MODIFY_SELF */
|
||||
.ascii "R=$?\n"
|
||||
.ascii "\n"
|
||||
.ascii "if [ $R -eq 126 ] && [ \"$(uname -m)\" != x86_64 ]; then\n"
|
||||
.ascii "if Q=\"$(command -v qemu-x86_64)\"; then\n"
|
||||
.ascii "exec \"$Q\" \"$0\" \"$@\"\n"
|
||||
.ascii "exec \"$Q\" \"$o\" \"$@\"\n"
|
||||
.ascii "else\n"
|
||||
.ascii "echo error: need qemu-x86_64 >&2\n"
|
||||
.ascii "fi\n"
|
||||
#ifndef APE_NO_MODIFY_SELF
|
||||
.ascii "elif [ $R -eq 127 ]; then\n" # means argv[0] was wrong
|
||||
.ascii " exec \"$o\" \"$@\"\n" # so do a path resolution
|
||||
#endif /* APE_NO_MODIFY_SELF */
|
||||
.ascii "fi\n"
|
||||
.ascii "exit $R\n"
|
||||
.endobj apesh
|
||||
|
|
|
@ -46,5 +46,10 @@ o/ape/idata.inc: \
|
|||
$(APE_OBJS): $(BUILD_FILES) \
|
||||
ape/ape.mk
|
||||
|
||||
o/$(MODE)/ape/ape-no-modify-self.o: ape/ape.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -DAPE_NO_MODIFY_SELF $<
|
||||
|
||||
.PHONY: o/$(MODE)/ape
|
||||
o/$(MODE)/ape: $(APE) $(APE_CHECKS)
|
||||
o/$(MODE)/ape: $(APE) \
|
||||
$(APE_CHECKS) \
|
||||
o/$(MODE)/ape/ape-no-modify-self.o
|
||||
|
|
|
@ -6,6 +6,7 @@ o/$(MODE)/test/libc/release/cosmopolitan.zip: \
|
|||
o/$(MODE)/ape/ape.lds \
|
||||
o/$(MODE)/libc/crt/crt.o \
|
||||
o/$(MODE)/ape/ape.o \
|
||||
o/$(MODE)/ape/ape-no-modify-self.o \
|
||||
o/$(MODE)/cosmopolitan.a
|
||||
@$(COMPILE) -AZIP -T$@ zip -j $@ $^
|
||||
|
||||
|
@ -37,6 +38,30 @@ o/$(MODE)/test/libc/release/smoke.com.dbg: \
|
|||
o/$(MODE)/ape/ape.o \
|
||||
o/$(MODE)/cosmopolitan.a
|
||||
|
||||
o/$(MODE)/test/libc/release/smoke-nms.com.dbg: \
|
||||
test/libc/release/smoke.c \
|
||||
o/cosmopolitan.h \
|
||||
o/$(MODE)/ape/ape.lds \
|
||||
o/$(MODE)/libc/crt/crt.o \
|
||||
o/$(MODE)/ape/ape-no-modify-self.o \
|
||||
o/$(MODE)/cosmopolitan.a
|
||||
@$(COMPILE) -ACC $(CC) \
|
||||
-o $@ \
|
||||
-Os \
|
||||
-static \
|
||||
-no-pie \
|
||||
-fno-pie \
|
||||
-nostdlib \
|
||||
-nostdinc \
|
||||
-mno-red-zone \
|
||||
-fno-omit-frame-pointer \
|
||||
-Wl,-T,o/$(MODE)/ape/ape.lds \
|
||||
-include o/cosmopolitan.h \
|
||||
test/libc/release/smoke.c \
|
||||
o/$(MODE)/libc/crt/crt.o \
|
||||
o/$(MODE)/ape/ape-no-modify-self.o \
|
||||
o/$(MODE)/cosmopolitan.a
|
||||
|
||||
o/$(MODE)/test/libc/release/smokecxx.com: \
|
||||
o/$(MODE)/test/libc/release/smokecxx.com.dbg
|
||||
@$(COMPILE) -AOBJCOPY -T$< $(OBJCOPY) -S -O binary $< $@
|
||||
|
@ -116,6 +141,8 @@ o/$(MODE)/test/libc/release/emulate.ok: \
|
|||
o/$(MODE)/test/libc/release: \
|
||||
o/$(MODE)/test/libc/release/smoke.com \
|
||||
o/$(MODE)/test/libc/release/smoke.com.runs \
|
||||
o/$(MODE)/test/libc/release/smoke-nms.com \
|
||||
o/$(MODE)/test/libc/release/smoke-nms.com.runs \
|
||||
o/$(MODE)/test/libc/release/smokecxx.com \
|
||||
o/$(MODE)/test/libc/release/smokecxx.com.runs \
|
||||
o/$(MODE)/test/libc/release/smokeansi.com \
|
||||
|
|
Loading…
Add table
Reference in a new issue