Skip to content

Commit

Permalink
ape loaders modify argv[0] for older binaries
Browse files Browse the repository at this point in the history
This repurposes one of the ELF padding bytes for a flag that is always 1
for modern ape binaries. If it is set, then the loader can safely assume
that the binary knows about the register for program_executable_name. If
it is not set, then the loader will unconditionally reset argv[0] to the
located exe. This makes preserve-argv[0] backwards-compatible with older
binaries.
  • Loading branch information
mrdomino committed May 6, 2024
1 parent a632695 commit bf6206f
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 3 deletions.
7 changes: 6 additions & 1 deletion ape/ape-m1.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ struct Syslib {
#define PT_INTERP 3
#define EI_CLASS 4
#define EI_DATA 5
#define EI_APE_FLAGS 9
#define PF_X 1
#define PF_W 2
#define PF_R 4
Expand Down Expand Up @@ -799,7 +800,7 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
}

static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
const char *exe, int fd, long *sp, long *auxv,
char *exe, int fd, long *sp, long *auxv,
char *execfn) {
long i, rc;
unsigned size;
Expand All @@ -814,6 +815,10 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
if (e->e_ident[EI_CLASS] == ELFCLASS32) {
return "32-bit ELF isn't supported";
}
if (!e->e_ident[EI_APE_FLAGS]) {
/* change argv[0] to resolved path */
((char **)(sp + 1))[0] = exe;
}
if (e->e_type != ET_EXEC && e->e_type != ET_DYN) {
return "ELF not ET_EXEC or ET_DYN";
}
Expand Down
5 changes: 3 additions & 2 deletions ape/ape.S
Original file line number Diff line number Diff line change
Expand Up @@ -661,8 +661,9 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
.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 "\\1" // 9: ape flags
.ascii "\\0\\0" // padding 2/6
.ascii "\\0\\0\\0\\0" // padding 4/6
.ascii "\\2\\0" // 10: εxεcµταblε
.ascii "\\076\\0" // 12: NexGen32e
.ascii "\\1\\0\\0\\0" // 14: elf v1.o
Expand Down
5 changes: 5 additions & 0 deletions ape/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
#define PT_INTERP 3
#define EI_CLASS 4
#define EI_DATA 5
#define EI_APE_FLAGS 9
#define PF_X 1
#define PF_W 2
#define PF_R 4
Expand Down Expand Up @@ -822,6 +823,10 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
if (e->e_ident[EI_CLASS] == ELFCLASS32) {
return "32-bit ELF isn't supported";
}
if (!e->e_ident[EI_APE_FLAGS]) {
/* change argv[0] to resolved path */
((char **)(sp + 1))[0] = exe;
}
if (e->e_type != ET_EXEC && e->e_type != ET_DYN) {
return "ELF not ET_EXEC or ET_DYN";
}
Expand Down

0 comments on commit bf6206f

Please sign in to comment.