mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Embed APE loader inside APE (#267)
The `ape-no-modify-self.o` bootloader now has an mmap-based payload that helps read-only APE binaries be load faster since it doesn't need to copy any files.
This commit is contained in:
parent
b5f743cdc3
commit
18ccfeb919
3 changed files with 39 additions and 3 deletions
26
ape/ape.S
26
ape/ape.S
|
@ -540,11 +540,30 @@ apesh: .ascii "'\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"
|
||||
// Try to use a system-wide APE loader.
|
||||
.ascii "type ape-loader >/dev/null 2>&1 && "
|
||||
.ascii "exec ape-loader \"$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\" ] || {\ndd 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 700 \"$t\"\n}\n"
|
||||
.ascii "exec \"$t\" \"$o\" \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
#endif
|
||||
#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"
|
||||
#ifdef APE_BUILDSAFE
|
||||
// This code is intended for binaries in build/bootstrap/. It
|
||||
// causes them to not self-modify since they're checked-in to
|
||||
|
@ -645,6 +664,11 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang
|
|||
.ascii "fi\n"
|
||||
.ascii "exit $R\n"
|
||||
.endobj apesh
|
||||
#ifdef APE_LOADER
|
||||
.section .ape.loader,"a",@progbits
|
||||
.incbin APE_LOADER
|
||||
.previous
|
||||
#endif /* APE_LOADER */
|
||||
#endif /* SupportsWindows() || SupportsMetal() || SupportsXnu() */
|
||||
|
||||
#if SupportsSystemv() || SupportsMetal()
|
||||
|
|
12
ape/ape.lds
12
ape/ape.lds
|
@ -370,6 +370,15 @@ SECTIONS {
|
|||
} :Ram
|
||||
|
||||
/*END: file content that's loaded by o/s */
|
||||
/*BEGIN: payload (for now, only the APE loader) */
|
||||
.payload ALIGN(64) : {
|
||||
/* Loader */
|
||||
HIDDEN(ape_loader = .);
|
||||
KEEP(*(.ape.loader))
|
||||
. = ALIGN(64);
|
||||
HIDDEN(ape_loader_end = .);
|
||||
}
|
||||
/*END: payload */
|
||||
/*BEGIN: bss memory void */
|
||||
|
||||
.zip . : {
|
||||
|
@ -511,6 +520,9 @@ HIDDEN(ape_bss_filesz = 0);
|
|||
HIDDEN(ape_bss_memsz = SIZEOF(.bss));
|
||||
HIDDEN(ape_bss_align = PAGESIZE);
|
||||
|
||||
SHSTUB2(ape_loader_dd_skip, RVA(ape_loader) / 64);
|
||||
SHSTUB2(ape_loader_dd_count, (ape_loader_end - ape_loader) / 64);
|
||||
|
||||
#if SupportsXnu()
|
||||
SHSTUB2(ape_macho_dd_skip, RVA(ape_macho) / 8);
|
||||
SHSTUB2(ape_macho_dd_count, (ape_macho_end - ape_macho) / 8);
|
||||
|
|
|
@ -51,8 +51,8 @@ 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 $<
|
||||
o/$(MODE)/ape/ape-no-modify-self.o: ape/ape.S o/$(MODE)/examples/loader.elf
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -DAPE_LOADER="\"o/$(MODE)/examples/loader.elf\"" -DAPE_NO_MODIFY_SELF $<
|
||||
|
||||
o/$(MODE)/ape/ape-buildsafe.o: ape/ape.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -DAPE_BUILDSAFE $<
|
||||
|
|
Loading…
Reference in a new issue