mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-16 23:50:32 +00:00
Loaders rewrite argv[0] for old binaries (#1170)
For this to work, a loader has to be able to tell the difference between an ‘old’ and a ‘new’ binary. This is achieved via a repurposing of ELF’s e_flags field. We previously tried to use the padding in e_ident for it, but binutils was resetting it to zero in e.g. strip. This introduces one new ELF flag for cosmopolitan binaries. It is called `EF_APE_MODERN`. We choose 0x101ca75, "lol cat 5". It should now be safe to install the ape loader binfmt registration with the `P` flag.
This commit is contained in:
parent
57c0b065c8
commit
7d31fc311a
5 changed files with 27 additions and 3 deletions
|
@ -146,6 +146,9 @@ struct Syslib {
|
|||
#define AT_RANDOM 25
|
||||
#define AT_EXECFN 31
|
||||
|
||||
#define EF_APE_MODERN 0x101ca75
|
||||
#define EF_APE_MODERN_MASK 0x1ffffff
|
||||
|
||||
#define AUXV_WORDS 31
|
||||
|
||||
/* from the xnu codebase */
|
||||
|
@ -799,7 +802,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;
|
||||
|
@ -820,6 +823,10 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
|
|||
if (e->e_machine != EM_AARCH64) {
|
||||
return "couldn't find ELF header with ARM64 machine type";
|
||||
}
|
||||
if ((e->e_flags & EF_APE_MODERN_MASK) != EF_APE_MODERN && sp[0] > 0) {
|
||||
/* change argv[0] to resolved path for older binaries */
|
||||
((char **)(sp + 1))[0] = exe;
|
||||
}
|
||||
if (e->e_phentsize != sizeof(struct ElfPhdr)) {
|
||||
Pexit(exe, 0, "e_phentsize is wrong");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue