From 89c4adad50fb222b271face4ebb75c944e3b40be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C5=8Dshin?= Date: Tue, 19 Dec 2023 10:31:27 -0500 Subject: [PATCH] Try to use x4 instead of x2 Also adds os as x3. May get aarch64 FreeBSD working. cosmo now traps on unsupported os, and cosmo and Launch both take os and exename at the same registers. __program_executable_name is a decentralized init on x64, so shouldn't be paid for if not used. --- ape/ape-m1.c | 8 ++--- ape/launch.S | 15 ++++----- ape/loader.c | 4 +-- libc/crt/crt.S | 6 ++-- libc/nexgen32e/program_executable_name.S | 32 +++++++++++++++++++ ...able_name.c => program_executable_name2.c} | 3 ++ libc/runtime/cosmo2.c | 28 ++++++++++------ 7 files changed, 69 insertions(+), 27 deletions(-) create mode 100644 libc/nexgen32e/program_executable_name.S rename libc/nexgen32e/{program_executable_name.c => program_executable_name2.c} (97%) diff --git a/ape/ape-m1.c b/ape/ape-m1.c index 874f452e1..75f8c85dd 100644 --- a/ape/ape-m1.c +++ b/ape/ape-m1.c @@ -725,12 +725,12 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd, close(fd); register long *x0 __asm__("x0") = sp; - register char *x2 __asm__("x2") = path; + register int x3 __asm__("x3") = 8 /* XNU */; + register char *x4 __asm__("x4") = path; register struct Syslib *x15 __asm__("x15") = lib; register long x16 __asm__("x16") = e->e_entry; __asm__ volatile("mov\tx1,#0\n\t" - "mov\tx3,#0\n\t" - "mov\tx4,#0\n\t" + "mov\tx2,#0\n\n" "mov\tx5,#0\n\t" "mov\tx6,#0\n\t" "mov\tx7,#0\n\t" @@ -758,7 +758,7 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd, "mov\tx0,#0\n\t" "br\tx16" : /* no outputs */ - : "r"(x0), "r"(x2), "r"(x15), "r"(x16) + : "r"(x0), "r"(x3), "r"(x4), "r"(x15), "r"(x16) : "memory"); __builtin_unreachable(); } diff --git a/ape/launch.S b/ape/launch.S index 87489f9f5..1e8ec9b06 100644 --- a/ape/launch.S +++ b/ape/launch.S @@ -31,17 +31,17 @@ // // @param rdi is passed through as-is // @param rsi is address of entrypoint (becomes zero) -// @param rdx is passed through as-is -// @param rcx is stack pointer (becomes r8) +// @param rdx is stack pointer (becomes zero) +// @param rcx is passed through as-is +// @param r8 is passed through as-is // @noreturn Launch: #ifdef __aarch64__ mov x16,x1 - mov sp,x3 + mov sp,x2 mov x1,0 - mov x3,x4 - mov x4,0 + mov x2,0 mov x5,0 mov x6,0 mov x7,0 @@ -70,9 +70,6 @@ Launch: #else - mov %rcx,%rsp - mov %r8,%rcx - xor %r8d,%r8d xor %r9d,%r9d xor %r10d,%r10d xor %r11d,%r11d @@ -80,6 +77,8 @@ Launch: xor %r13d,%r13d xor %r14d,%r14d xor %r15d,%r15d + mov %rdx,%rsp + xor %edx,%edx push %rsi xor %esi,%esi xor %ebp,%ebp diff --git a/ape/loader.c b/ape/loader.c index ece126229..debe23a3b 100644 --- a/ape/loader.c +++ b/ape/loader.c @@ -225,7 +225,7 @@ struct ApeLoader { EXTERN_C long SystemCall(long, long, long, long, long, long, long, int); EXTERN_C void -Launch(void *, long, void *, void *, int) __attribute__((__noreturn__)); +Launch(void *, long, void *, int, void *) __attribute__((__noreturn__)); extern char __executable_start[]; extern char _end[]; @@ -768,7 +768,7 @@ __attribute__((__noreturn__)) static void Spawn(int os, char *exe, int fd, Msyscall(dynbase + code, codesize, os); /* call program entrypoint */ - Launch(IsFreebsd() ? sp : 0, dynbase + e->e_entry, exe, sp, os); + Launch(IsFreebsd() ? sp : 0, dynbase + e->e_entry, sp, os, exe); } static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf, diff --git a/libc/crt/crt.S b/libc/crt/crt.S index 07978f47b..c8cd21383 100644 --- a/libc/crt/crt.S +++ b/libc/crt/crt.S @@ -62,8 +62,6 @@ _start: // set operating system when already detected 1: mov %cl,__hostos(%rip) - mov %rdx,__program_executable_name(%rip) - // get startup timestamp as early as possible // its used by --strace flag and kprintf() %T rdtsc @@ -142,7 +140,9 @@ _start: // should be set to zero on other platforms mov x1,x15 -// third arg (x2) is the program path passed by ape-m1.c +// 3rd arg (x2) is unused (stack pointer on x86_64) +// 4th arg (x3) is os passed by loader +// 5th arg (x4) is program executable name passed by loader // switch to c code bl cosmo diff --git a/libc/nexgen32e/program_executable_name.S b/libc/nexgen32e/program_executable_name.S new file mode 100644 index 000000000..8d88cc1f1 --- /dev/null +++ b/libc/nexgen32e/program_executable_name.S @@ -0,0 +1,32 @@ +/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2023 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.internal.h" +#include "libc/notice.inc" + + .initbss 300,_init_program_executable_name +// Global variable holding the binary that we are running as +__program_executable_name: + .quad 0 + .endobj __program_executable_name,globl + .previous + + .init.start 300,_init_program_executable_name + mov %r8,%rax + stosq + .init.end 300,_init_program_executable_name diff --git a/libc/nexgen32e/program_executable_name.c b/libc/nexgen32e/program_executable_name2.c similarity index 97% rename from libc/nexgen32e/program_executable_name.c rename to libc/nexgen32e/program_executable_name2.c index bbc9a1183..4186c825d 100644 --- a/libc/nexgen32e/program_executable_name.c +++ b/libc/nexgen32e/program_executable_name2.c @@ -17,5 +17,8 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/runtime/runtime.h" +#ifndef __x86_64__ char *__program_executable_name; + +#endif /* __x86_64__ */ diff --git a/libc/runtime/cosmo2.c b/libc/runtime/cosmo2.c index 57067b5ab..dec01e8d0 100644 --- a/libc/runtime/cosmo2.c +++ b/libc/runtime/cosmo2.c @@ -78,7 +78,8 @@ static const char *DecodeMagnum(const char *p, long *r) { return *r = x, p; } -wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename) { +wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, int, int os, + char *exename) { // get startup timestamp as early as possible // its used by --strace and also kprintf() %T @@ -112,17 +113,24 @@ wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename) { program_invocation_name = argv[0]; __oldstack = (intptr_t)sp; - // detect apple m1 environment const char *magnums; - if (SupportsXnu() && (__syslib = m1)) { - hostos = _HOSTXNU; - magnums = syscon_xnu; - } else if (SupportsLinux()) { - hostos = _HOSTLINUX; - magnums = syscon_linux; - } else { - notpossible; + switch (os) { + case _HOSTXNU: { + npassert(SupportsXnu() && m1); + __syslib = m1; + magnums = syscon_xnu; + break; + } + case _HOSTLINUX: { + npassert(SupportsLinux()); + magnums = syscon_linux; + break; + } + default: { + npassert(!"supported-os"); + } } + hostos = os; // setup system magic numbers for (long *mp = syscon_start; mp < syscon_end; ++mp) {