Improve aarch64 native support some more

This change introduces partial support for automating remote testing of
aarch64 binaries on Raspberry Pi and Apple Silicon.
This commit is contained in:
Justine Tunney 2023-06-04 08:19:45 -07:00
parent fc34ba2596
commit 4aa1d09b9e
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
20 changed files with 185 additions and 82 deletions

View file

@ -313,7 +313,7 @@ static errno_t CloneOpenbsd(int (*func)(void *, int), char *stk, size_t stksz,
sp &= -alignof(struct __tfork);
tf = (struct __tfork *)sp;
sp -= sizeof(struct CloneArgs);
sp &= -MAX(16, alignof(struct CloneArgs));
sp &= -alignof(struct CloneArgs);
wt = (struct CloneArgs *)sp;
wt->ctid = flags & CLONE_CHILD_SETTID ? ctid : &wt->tid;
wt->ztid = flags & CLONE_CHILD_CLEARTID ? ctid : &wt->tid;
@ -442,10 +442,10 @@ static int CloneNetbsd(int (*func)(void *, int), char *stk, size_t stksz,
static void *SiliconThreadMain(void *arg) {
register struct CloneArgs *wt asm("x21") = arg;
asm volatile("ldr\tx28,%0" : /* no outputs */ : "m"(wt->tls));
*wt->ctid = wt->this;
register long x0 asm("x0") = (long)wt->arg;
register long x1 asm("x1") = (long)wt->tid;
register void *x0 asm("x0") = wt->arg;
register int x1 asm("w1") = wt->this;
register void *x28 asm("x28") = wt->tls;
asm volatile("mov\tx19,x29\n\t" // save frame pointer
"mov\tx20,sp\n\t" // save stack pointer
"mov\tx29,#0\n\t" // reset backtrace
@ -454,7 +454,7 @@ static void *SiliconThreadMain(void *arg) {
"mov\tx29,x19\n\t" // restore frame pointer
"mov\tsp,x20" // restore stack pointer
: "+r"(x0)
: "r"(x1), "r"(wt->func), "r"(wt)
: "r"(x1), "r"(wt->func), "r"(wt), "r"(x28)
: "x19", "x20", "memory");
*wt->ztid = 0;
return 0;

View file

@ -19,6 +19,7 @@
#include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h"
#include "libc/macros.internal.h"
#include "libc/nexgen32e/rdtsc.h"
@ -44,12 +45,12 @@ typedef int init_f(int argc, char **argv, char **envp, unsigned long *auxv);
extern long syscon_start[];
extern long syscon_end[];
extern long syscon_linux[];
extern long syscon_xnu[];
extern long syscon_freebsd[];
extern long syscon_openbsd[];
extern long syscon_netbsd[];
extern long syscon_windows[];
extern char syscon_linux[];
extern char syscon_xnu[];
extern char syscon_freebsd[];
extern char syscon_openbsd[];
extern char syscon_netbsd[];
extern char syscon_windows[];
extern init_f __strace_init;
extern init_f *__preinit_array_start[] __attribute__((__weak__));
extern init_f *__preinit_array_end[] __attribute__((__weak__));
@ -61,13 +62,24 @@ extern char ape_stack_prot[] __attribute__((__weak__));
extern pthread_mutex_t __mmi_lock_obj;
extern int hostos asm("__hostos");
static const char *DecodeMagnum(const char *p, long *r) {
int k = 0;
unsigned long c, x = 0;
do {
c = *p++;
x |= (c & 127) << k;
k += 7;
} while (c & 128);
return *r = x, p;
}
textstartup void cosmo(long *sp, struct Syslib *m1) {
int argc;
long *mp;
init_f **fp;
uintptr_t *pp;
long *mp, *magnums;
char **argv, **envp;
unsigned long *auxv;
char **argv, **envp, *magnums;
// get startup timestamp as early as possible
// its used by --strace and also kprintf() %T
@ -93,7 +105,7 @@ textstartup void cosmo(long *sp, struct Syslib *m1) {
// setup system magic numbers
for (mp = syscon_start; mp < syscon_end; ++mp) {
*mp = *magnums++;
magnums = DecodeMagnum(magnums, mp);
}
// check system call abi compatibility
@ -131,6 +143,7 @@ textstartup void cosmo(long *sp, struct Syslib *m1) {
#endif
#endif
// initialize file system
InitializeFileDescriptors();
// set helpful globals

View file

@ -61,9 +61,7 @@ textstartup void __set_tls(struct CosmoTib *tib) {
"d"((uint32_t)(val >> 32)));
}
#else
asm volatile("mov\tx28,%0" : /* no outputs */ : "r"(tib));
if (!IsXnu()) {
asm volatile("msr\ttpidr_el0,%0" : /* no outputs */ : "r"(tib));
}
register long x28 asm("x28") = (long)tib;
asm volatile("" : "+r"(x28));
#endif
}

View file

@ -67,13 +67,13 @@ vfork:
#endif
pop %rbp
#endif
mov %fs:0,%r9 # get thread information block
mov %fs:0,%r9 // get thread information block
#if SupportsWindows()
testb IsWindows()
jnz 6f # and we're lucky to have that
jnz 6f // and we're lucky to have that
#endif
#ifdef __SANITIZE_ADDRESS__
jmp 5f # TODO: asan and vfork don't mix?
jmp 5f // TODO: asan and vfork don't mix?
#endif
#if SupportsXnu()
testb IsXnu()
@ -81,10 +81,10 @@ vfork:
#endif
#if SupportsOpenbsd()
testb IsOpenbsd()
jnz 5f # fake vfork plus msyscall issues
jnz 5f // fake vfork plus msyscall issues
#endif
mov 0x3c(%r9),%r8d # avoid question of @vforksafe errno
pop %rsi # saves return address in a register
mov 0x3c(%r9),%r8d // avoid question of @vforksafe errno
pop %rsi // saves return address in a register
mov __NR_vfork(%rip),%eax
#if SupportsBsd()
clc
@ -95,10 +95,10 @@ vfork:
neg %rax
0:
#endif
push %rsi # note it happens twice in same page
push %rsi // note it happens twice in same page
cmp $-4095,%eax
jae systemfive_error
mov %r8d,0x3c(%r9) # restore errno
mov %r8d,0x3c(%r9) // restore errno
1: test %eax,%eax
jnz .Lpar
.Lchi: orb $TIB_FLAG_VFORKED,0x40(%r9)
@ -121,7 +121,7 @@ vfork:
mov %rsp,%rbp
push %r9
push %r9
xor %edi,%edi # dwCreationFlags
xor %edi,%edi // dwCreationFlags
call sys_fork_nt
pop %r9
pop %r9
@ -131,11 +131,31 @@ vfork:
#elif defined(__aarch64__)
mov x8,#220 // __NR_clone
adrp x0,__hostos
ldr w0,[x0,#:lo12:__hostos]
tbz x0,3,1f // bit 3 is xnu
b fork // which doesn't support vfork()
1: mov x8,#220 // __NR_clone
mov x0,#0x4111 // SIGCHLD | CLONE_VM | CLONE_VFORK
mov x1,#0
svc 0
.hidden _sysret
// if (!rc) {
// __get_tls()->tib_flags |= TIB_FLAG_VFORKED;
// } else {
// __get_tls()->tib_flags &= ~TIB_FLAG_VFORKED;
// }
sub x1,x28,#1152
ldr x2,[x1,0x40]
cbnz x0,2f
orr x2,x2,#TIB_FLAG_VFORKED
1: str x2,[x1,0x40]
b 3f
2: and x2,x2,#~TIB_FLAG_VFORKED
b 1b
// if (rc < 0) errno = -rc, rc = -1;
3: .hidden _sysret
b _sysret
#else