mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-05 09:20:29 +00:00
Loaders rewrite argv[0] for old binaries
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`, and it is bit 1. It should now be safe to install the ape loader binfmt registration with the `P` flag.
This commit is contained in:
parent
06d916b449
commit
736fc75965
5 changed files with 20 additions and 3 deletions
|
@ -124,6 +124,7 @@ struct Syslib {
|
|||
#define PT_INTERP 3
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define EF_APE_MODERN 1
|
||||
#define PF_X 1
|
||||
#define PF_W 2
|
||||
#define PF_R 4
|
||||
|
@ -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;
|
||||
|
@ -820,6 +821,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)) {
|
||||
/* 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");
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ ape_mz:
|
|||
.quad ape_elf_entry // 18: e_entry
|
||||
.quad ape_elf_phoff // 20: e_phoff
|
||||
.quad ape_elf_shoff // 28: e_shoff
|
||||
.long 0 // 30: e_flags
|
||||
.long 1 // 30: e_flags
|
||||
.short 64 // 34: e_ehsize
|
||||
.short 56 // 36: e_phentsize
|
||||
.short ape_elf_phnum // 38: e_phnum
|
||||
|
@ -669,7 +669,7 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
|
|||
.shstub ape_elf_entry,8 // 18: e_entry
|
||||
.shstub ape_elf_phoff,8 // 20: e_phoff
|
||||
.shstub ape_elf_shoff,8 // 28: e_shoff
|
||||
.ascii "\\0\\0\\0\\0" // 30: e_flags
|
||||
.ascii "\\1\\0\\0\\0" // 30: e_flags
|
||||
.ascii "\\100\\0" // 34: e_ehsize
|
||||
.ascii "\\070\\0" // 36: e_phentsize
|
||||
.shstub ape_elf_phnum,2 // 38: e_phnum
|
||||
|
|
|
@ -134,6 +134,7 @@
|
|||
#define PT_INTERP 3
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define EF_APE_MODERN 1
|
||||
#define PF_X 1
|
||||
#define PF_W 2
|
||||
#define PF_R 4
|
||||
|
@ -834,6 +835,10 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
|
|||
return "couldn't find ELF header with x86-64 machine type";
|
||||
}
|
||||
#endif
|
||||
if (!(e->e_flags & EF_APE_MODERN)) {
|
||||
/* change argv[0] to resolved path for older binaries */
|
||||
((char **)(sp + 1))[0] = exe;
|
||||
}
|
||||
if (e->e_phentsize != sizeof(struct ElfPhdr)) {
|
||||
Pexit(os, exe, 0, "e_phentsize is wrong");
|
||||
}
|
||||
|
|
|
@ -85,6 +85,8 @@
|
|||
#define EM_RISCV 243
|
||||
#define EM_BPF 247
|
||||
|
||||
#define EF_APE_MODERN 1
|
||||
|
||||
#define GRP_COMDAT 1
|
||||
#define STN_UNDEF 0
|
||||
|
||||
|
|
|
@ -331,6 +331,10 @@ static void UseFreebsdOsAbi(void) {
|
|||
elf->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
|
||||
}
|
||||
|
||||
static void WriteApeFlags(void) {
|
||||
elf->e_flags |= EF_APE_MODERN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Improve GCC11 `-fpatchable-function-entry` codegen.
|
||||
*
|
||||
|
@ -692,6 +696,7 @@ static void FixupObject(void) {
|
|||
}
|
||||
}
|
||||
if (elf->e_type != ET_REL) {
|
||||
WriteApeFlags();
|
||||
PurgeIfuncSections();
|
||||
RelinkZipFiles();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue