mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
aarch64 loader passes os (#1042)
* Reorder Launch arguments, pass aarch64 os Third and fourth arguments are now identical between cosmo and Launch. By passing sp as argument 4, we save a bit of register juggling. Fourth argument (os) is now always passed by the loader on aarch64. It is not yet processed by cosmo. Pushing this change separately, as the cosmo side turns out to be somewhat more involved. * cosmo2 receives os from loader FreeBSD aarch64 now traps early rather than pretending to be Linux. o/aarch64/examples/env.com still works on Linux and Xnu.
This commit is contained in:
parent
d8ad34686a
commit
14fe83facd
5 changed files with 30 additions and 20 deletions
|
@ -726,10 +726,10 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
|
||||||
|
|
||||||
register long *x0 __asm__("x0") = sp;
|
register long *x0 __asm__("x0") = sp;
|
||||||
register char *x2 __asm__("x2") = path;
|
register char *x2 __asm__("x2") = path;
|
||||||
|
register int x3 __asm__("x3") = 8; /* _HOSTXNU */
|
||||||
register struct Syslib *x15 __asm__("x15") = lib;
|
register struct Syslib *x15 __asm__("x15") = lib;
|
||||||
register long x16 __asm__("x16") = e->e_entry;
|
register long x16 __asm__("x16") = e->e_entry;
|
||||||
__asm__ volatile("mov\tx1,#0\n\t"
|
__asm__ volatile("mov\tx1,#0\n\t"
|
||||||
"mov\tx3,#0\n\t"
|
|
||||||
"mov\tx4,#0\n\t"
|
"mov\tx4,#0\n\t"
|
||||||
"mov\tx5,#0\n\t"
|
"mov\tx5,#0\n\t"
|
||||||
"mov\tx6,#0\n\t"
|
"mov\tx6,#0\n\t"
|
||||||
|
@ -758,7 +758,7 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
|
||||||
"mov\tx0,#0\n\t"
|
"mov\tx0,#0\n\t"
|
||||||
"br\tx16"
|
"br\tx16"
|
||||||
: /* no outputs */
|
: /* no outputs */
|
||||||
: "r"(x0), "r"(x2), "r"(x15), "r"(x16)
|
: "r"(x0), "r"(x2), "r"(x3), "r"(x15), "r"(x16)
|
||||||
: "memory");
|
: "memory");
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,15 +32,15 @@
|
||||||
// @param rdi is passed through as-is
|
// @param rdi is passed through as-is
|
||||||
// @param rsi is address of entrypoint (becomes zero)
|
// @param rsi is address of entrypoint (becomes zero)
|
||||||
// @param rdx is passed through as-is
|
// @param rdx is passed through as-is
|
||||||
// @param rcx is stack pointer (becomes r8)
|
// @param rcx is passed through as-is
|
||||||
|
// @param r8 is stack pointer (becomes zero)
|
||||||
// @noreturn
|
// @noreturn
|
||||||
Launch:
|
Launch:
|
||||||
#ifdef __aarch64__
|
#ifdef __aarch64__
|
||||||
|
|
||||||
mov x16,x1
|
mov x16,x1
|
||||||
mov sp,x3
|
mov sp,x4
|
||||||
mov x1,0
|
mov x1,0
|
||||||
mov x3,x4
|
|
||||||
mov x4,0
|
mov x4,0
|
||||||
mov x5,0
|
mov x5,0
|
||||||
mov x6,0
|
mov x6,0
|
||||||
|
@ -70,8 +70,7 @@ Launch:
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
mov %rcx,%rsp
|
mov %r8,%rsp
|
||||||
mov %r8,%rcx
|
|
||||||
xor %r8d,%r8d
|
xor %r8d,%r8d
|
||||||
xor %r9d,%r9d
|
xor %r9d,%r9d
|
||||||
xor %r10d,%r10d
|
xor %r10d,%r10d
|
||||||
|
|
|
@ -224,7 +224,7 @@ struct ApeLoader {
|
||||||
};
|
};
|
||||||
|
|
||||||
EXTERN_C long SystemCall(long, long, long, long, long, long, long, int);
|
EXTERN_C long SystemCall(long, long, long, long, long, long, long, int);
|
||||||
EXTERN_C void Launch(void *, long, void *, void *, int)
|
EXTERN_C void Launch(void *, long, void *, int, void *)
|
||||||
__attribute__((__noreturn__));
|
__attribute__((__noreturn__));
|
||||||
|
|
||||||
extern char __executable_start[];
|
extern char __executable_start[];
|
||||||
|
@ -768,7 +768,7 @@ __attribute__((__noreturn__)) static void Spawn(int os, char *exe, int fd,
|
||||||
Msyscall(dynbase + code, codesize, os);
|
Msyscall(dynbase + code, codesize, os);
|
||||||
|
|
||||||
/* call program entrypoint */
|
/* call program entrypoint */
|
||||||
Launch(IsFreebsd() ? sp : 0, dynbase + e->e_entry, exe, sp, os);
|
Launch(IsFreebsd() ? sp : 0, dynbase + e->e_entry, exe, os, sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
|
static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
|
||||||
|
|
|
@ -127,7 +127,7 @@ _start:
|
||||||
|
|
||||||
#if SupportsFreebsd()
|
#if SupportsFreebsd()
|
||||||
// save first arg
|
// save first arg
|
||||||
mov x3,x0
|
mov x4,x0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// save original stack pointer
|
// save original stack pointer
|
||||||
|
@ -147,7 +147,8 @@ _start:
|
||||||
// should be set to zero on other platforms
|
// should be set to zero on other platforms
|
||||||
mov x1,x15
|
mov x1,x15
|
||||||
|
|
||||||
// third arg (x2) is the program path passed by ape-m1.c
|
// third arg is program path passed by loader
|
||||||
|
// fourth arg is detected os passed by loader
|
||||||
|
|
||||||
// switch to c code
|
// switch to c code
|
||||||
bl cosmo
|
bl cosmo
|
||||||
|
|
|
@ -79,7 +79,7 @@ static const char *DecodeMagnum(const char *p, long *r) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename,
|
wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename,
|
||||||
long *is_freebsd) {
|
int os, long *is_freebsd) {
|
||||||
|
|
||||||
// get startup timestamp as early as possible
|
// get startup timestamp as early as possible
|
||||||
// its used by --strace and also kprintf() %T
|
// its used by --strace and also kprintf() %T
|
||||||
|
@ -117,17 +117,27 @@ wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename,
|
||||||
__program_executable_name = exename;
|
__program_executable_name = exename;
|
||||||
program_invocation_name = argv[0];
|
program_invocation_name = argv[0];
|
||||||
__oldstack = (intptr_t)sp;
|
__oldstack = (intptr_t)sp;
|
||||||
|
if (!(hostos = os)) {
|
||||||
|
if (SupportsFreebsd() && is_freebsd) {
|
||||||
|
hostos = _HOSTFREEBSD;
|
||||||
|
} else if (SupportsXnu() && m1) {
|
||||||
|
hostos = _HOSTXNU;
|
||||||
|
} else if (SupportsLinux()) {
|
||||||
|
hostos = _HOSTLINUX;
|
||||||
|
} else {
|
||||||
|
notpossible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// detect apple m1 environment
|
|
||||||
const char *magnums;
|
const char *magnums;
|
||||||
if (SupportsFreebsd() && is_freebsd) {
|
if (IsFreebsd()) {
|
||||||
hostos = _HOSTFREEBSD;
|
|
||||||
magnums = syscon_freebsd;
|
magnums = syscon_freebsd;
|
||||||
} else if (SupportsXnu() && (__syslib = m1)) {
|
} else if (IsXnu()) {
|
||||||
hostos = _HOSTXNU;
|
if (!(__syslib = m1)) {
|
||||||
|
notpossible;
|
||||||
|
}
|
||||||
magnums = syscon_xnu;
|
magnums = syscon_xnu;
|
||||||
} else if (SupportsLinux()) {
|
} else if (IsLinux()) {
|
||||||
hostos = _HOSTLINUX;
|
|
||||||
magnums = syscon_linux;
|
magnums = syscon_linux;
|
||||||
} else {
|
} else {
|
||||||
notpossible;
|
notpossible;
|
||||||
|
@ -139,7 +149,7 @@ wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename,
|
||||||
}
|
}
|
||||||
|
|
||||||
// check system call abi compatibility
|
// check system call abi compatibility
|
||||||
if (SupportsXnu() && __syslib && __syslib->__version < SYSLIB_VERSION) {
|
if (IsXnu() && __syslib->__version < SYSLIB_VERSION) {
|
||||||
sys_write(2, "need newer ape loader\n", 22);
|
sys_write(2, "need newer ape loader\n", 22);
|
||||||
_Exit(127);
|
_Exit(127);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue