mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 06:48:31 +00:00
Introduce native support for MacOS ARM64
There's a new program named ape/ape-m1.c which will be used to build an embeddable binary that can load ape and elf executables. The support is mostly working so far, but still chasing down ABI issues.
This commit is contained in:
parent
b852650c08
commit
1422e96b4e
757 changed files with 2988 additions and 1321 deletions
|
@ -30,6 +30,7 @@
|
|||
#include "libc/runtime/pc.internal.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
#define rdmsr(msr) \
|
||||
({ \
|
||||
|
@ -238,3 +239,5 @@ int arch_prctl(int code, int64_t addr) {
|
|||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
|
|
|
@ -192,7 +192,7 @@ XnuThreadMain(void *pthread, // rdi
|
|||
"syscall\n\t" // __bsdthread_terminate()
|
||||
"ud2"
|
||||
: "=m"(*wt->ztid)
|
||||
: "a"(0x2000000 | 361), "D"(0), "S"(0), "d"(0)
|
||||
: "a"(0x2000000 | 361), "D"(0), "S"(0), "d"(0L)
|
||||
: "rcx", "r10", "r11", "memory");
|
||||
notpossible;
|
||||
}
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#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"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#ifndef __x86_64__
|
||||
|
@ -33,15 +33,27 @@ int main(int, char **, char **) __attribute__((__weak__));
|
|||
|
||||
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 init_f __strace_init;
|
||||
extern init_f *__preinit_array_start[] __attribute__((__weak__));
|
||||
extern init_f *__preinit_array_end[] __attribute__((__weak__));
|
||||
extern init_f *__init_array_start[] __attribute__((__weak__));
|
||||
extern init_f *__init_array_end[] __attribute__((__weak__));
|
||||
extern pthread_mutex_t __mmi_lock_obj;
|
||||
extern int hostos asm("__hostos");
|
||||
|
||||
textstartup void cosmo(long *sp) {
|
||||
textstartup void cosmo(long *sp, struct Syslib *m1) {
|
||||
int argc;
|
||||
init_f **fp;
|
||||
uintptr_t *pp;
|
||||
long *mp, *magnums;
|
||||
char **argv, **envp;
|
||||
unsigned long *auxv;
|
||||
|
||||
|
@ -56,6 +68,20 @@ textstartup void cosmo(long *sp) {
|
|||
auxv = (unsigned long *)(sp + 1 + argc + 1);
|
||||
while (*auxv++) donothing;
|
||||
|
||||
// detect apple m1 environment
|
||||
if ((__syslib = m1)) {
|
||||
hostos = _HOSTXNU;
|
||||
magnums = syscon_xnu;
|
||||
} else {
|
||||
hostos = _HOSTLINUX;
|
||||
magnums = syscon_linux;
|
||||
}
|
||||
|
||||
// setup system magic numbers
|
||||
for (mp = syscon_start; mp < syscon_end; ++mp) {
|
||||
*mp = *magnums++;
|
||||
}
|
||||
|
||||
// needed by kisdangerous()
|
||||
__oldstack = (intptr_t)sp;
|
||||
__pid = sys_getpid().ax;
|
||||
|
@ -65,11 +91,6 @@ textstartup void cosmo(long *sp) {
|
|||
_mmi.p = _mmi.s;
|
||||
__mmi_lock_obj._type = PTHREAD_MUTEX_RECURSIVE;
|
||||
|
||||
#ifdef SYSDEBUG
|
||||
// initialize --strace functionality
|
||||
argc = __strace_init(argc, argv, envp, auxv);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if IsAsan()
|
||||
__asan_init(argc, argv, envp, auxv);
|
||||
|
@ -89,6 +110,9 @@ textstartup void cosmo(long *sp) {
|
|||
// run initialization callbacks
|
||||
_init();
|
||||
__enable_tls();
|
||||
#ifdef SYSDEBUG
|
||||
argc = __strace_init(argc, argv, envp, auxv);
|
||||
#endif
|
||||
for (fp = __init_array_end; fp-- > __init_array_start;) {
|
||||
(*fp)(argc, argv, envp, auxv);
|
||||
}
|
||||
|
|
|
@ -174,14 +174,15 @@ __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
|||
(0x7e000 - 0x79000 + sizeof(struct EfiArgs) + 4095) / 4096, &Address);
|
||||
Address = IMAGE_BASE_PHYSICAL;
|
||||
SystemTable->BootServices->AllocatePages(
|
||||
AllocateAddress, EfiRuntimeServicesData, ((_end - _base) + 4095) / 4096,
|
||||
&Address);
|
||||
AllocateAddress, EfiRuntimeServicesData,
|
||||
((_end - __executable_start) + 4095) / 4096, &Address);
|
||||
mm = (struct mman *)0x0500;
|
||||
SystemTable->BootServices->SetMem(mm, sizeof(*mm), 0);
|
||||
SystemTable->BootServices->SetMem(
|
||||
(void *)0x79000, 0x7e000 - 0x79000 + sizeof(struct EfiArgs), 0);
|
||||
SystemTable->BootServices->CopyMem((void *)IMAGE_BASE_PHYSICAL, _base,
|
||||
_end - _base);
|
||||
SystemTable->BootServices->CopyMem((void *)IMAGE_BASE_PHYSICAL,
|
||||
__executable_start,
|
||||
_end - __executable_start);
|
||||
|
||||
/*
|
||||
* Converts UEFI shell arguments to argv.
|
||||
|
|
|
@ -41,28 +41,28 @@ _EfiPostboot:
|
|||
mov %rdi,rMm
|
||||
mov %rdx,rArgc
|
||||
lea (rBane,%rcx),rArgv
|
||||
mov $PHYSICAL(.Ltmpstk),%rax # switch to temporary stack
|
||||
and $-16,%al # in physical space
|
||||
mov $PHYSICAL(.Ltmpstk),%rax // switch to temporary stack
|
||||
and $-16,%al // in physical space
|
||||
xchg %rax,%rsp
|
||||
mov $PHYSICAL(0f),%eax # resume execution in copied
|
||||
jmp *%rax # image
|
||||
0: mov $EFER,%ecx # enable syscall/sysret & nx
|
||||
mov $PHYSICAL(0f),%eax // resume execution in copied
|
||||
jmp *%rax // image
|
||||
0: mov $EFER,%ecx // enable syscall/sysret & nx
|
||||
rdmsr
|
||||
or $EFER_SCE|EFER_NXE,%eax
|
||||
wrmsr
|
||||
mov %rsi,%cr3 # load new page table
|
||||
add rBane,%rsp # we can now switch stack to
|
||||
add rBane,rMm # negative address space
|
||||
mov $1024*1024,%edx # set up virtual memory
|
||||
mov $1024*1024+_end,%ecx # mapping
|
||||
sub $_base,%ecx
|
||||
mov %rsi,%cr3 // load new page table
|
||||
add rBane,%rsp // we can now switch stack to
|
||||
add rBane,rMm // negative address space
|
||||
mov $1024*1024,%edx // set up virtual memory
|
||||
mov $1024*1024+_end,%ecx // mapping
|
||||
sub $__executable_start,%ecx
|
||||
call __map_phdrs
|
||||
mov $1f,%eax # switch rip to virtual
|
||||
jmp *%rax # address space
|
||||
mov $1f,%eax // switch rip to virtual
|
||||
jmp *%rax // address space
|
||||
1: push $0x037f
|
||||
fldcw (%rsp)
|
||||
.weak _gdtr
|
||||
lgdt _gdtr # switch to our own GDT
|
||||
lgdt _gdtr // switch to our own GDT
|
||||
mov $GDT_LONG_DATA,%ax
|
||||
mov %ax,%ds
|
||||
mov %ax,%ss
|
||||
|
@ -71,34 +71,34 @@ _EfiPostboot:
|
|||
mov %ax,%gs
|
||||
.weak ape_stack_vaddr
|
||||
.weak ape_stack_memsz
|
||||
movabs $ape_stack_vaddr,%rsp # switch to final stack in
|
||||
add $ape_stack_memsz,%rsp # virtual address space
|
||||
movl $0,0x7b000 # unmap null 2mb
|
||||
movabs $ape_stack_vaddr,%rsp // switch to final stack in
|
||||
add $ape_stack_memsz,%rsp // virtual address space
|
||||
movl $0,0x7b000 // unmap null 2mb
|
||||
mov rMm,%rdi
|
||||
xor %esi,%esi # free up now-unused pages
|
||||
xor %esi,%esi // free up now-unused pages
|
||||
xor %edx,%edx
|
||||
call __reclaim_boot_pages
|
||||
push .Lenv0(%rip) # envp[0][0]
|
||||
push .Lenv0(%rip) // envp[0][0]
|
||||
mov %rsp,%rbp
|
||||
push $0 # auxv[1][1]
|
||||
push $0 # auxv[1][0]
|
||||
push $0 // auxv[1][1]
|
||||
push $0 // auxv[1][0]
|
||||
mov (rArgv),%rax
|
||||
add rBane,%rax
|
||||
push %rax # auxv[0][1]
|
||||
push $31 # auxv[0][0] AT_EXECFN
|
||||
push $0 # envp[1]
|
||||
push %rbp # envp[0]
|
||||
push $0 # argv[argc] NULL
|
||||
lea -8(rArgv,rArgc,8),%rsi # push rest of argv, &
|
||||
mov rArgc,%rcx # adjust pointers to point to
|
||||
std # negative space
|
||||
push %rax // auxv[0][1]
|
||||
push $31 // auxv[0][0] AT_EXECFN
|
||||
push $0 // envp[1]
|
||||
push %rbp // envp[0]
|
||||
push $0 // argv[argc] NULL
|
||||
lea -8(rArgv,rArgc,8),%rsi // push rest of argv, &
|
||||
mov rArgc,%rcx // adjust pointers to point to
|
||||
std // negative space
|
||||
2: lodsq
|
||||
add rBane,%rax
|
||||
push %rax
|
||||
loop 2b
|
||||
cld
|
||||
push rArgc # argc
|
||||
pushpop _HOSTMETAL,%rcx # sets __hostos in crt.S
|
||||
push rArgc // argc
|
||||
pushpop _HOSTMETAL,%rcx // sets __hostos in crt.S
|
||||
xor %ebp,%ebp
|
||||
xor %eax,%eax
|
||||
xor %ebx,%ebx
|
||||
|
@ -124,3 +124,6 @@ _EfiPostboot:
|
|||
.space 0x1000
|
||||
.Ltmpstk:
|
||||
.previous
|
||||
|
||||
.weak __executable_start
|
||||
.weak _end
|
||||
|
|
|
@ -53,9 +53,9 @@ static privileged dontinline void FixupLockNops(void) {
|
|||
* binary the offsets of all the instructions we need to change.
|
||||
*/
|
||||
for (int *p = __threadcalls_start; p < __threadcalls_end; ++p) {
|
||||
_base[*p + 0] = 0x67;
|
||||
_base[*p + 1] = 0x67;
|
||||
_base[*p + 2] = 0xe8;
|
||||
__executable_start[*p + 0] = 0x67;
|
||||
__executable_start[*p + 1] = 0x67;
|
||||
__executable_start[*p + 2] = 0xe8;
|
||||
}
|
||||
__morph_end(&mask);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ _Alignas(TLS_ALIGNMENT) static char __static_tls[6016];
|
|||
*
|
||||
* Here's the TLS memory layout on aarch64:
|
||||
*
|
||||
* x28
|
||||
* %tpidr_el0
|
||||
* │
|
||||
* │ _Thread_local
|
||||
|
@ -82,7 +83,7 @@ _Alignas(TLS_ALIGNMENT) static char __static_tls[6016];
|
|||
* can disable it as follows:
|
||||
*
|
||||
* int main() {
|
||||
* __tls_enabled = false;
|
||||
* __tls_enabled_set(false);
|
||||
* // do stuff
|
||||
* }
|
||||
*
|
||||
|
@ -98,15 +99,15 @@ textstartup void __enable_tls(void) {
|
|||
|
||||
// Here's the layout we're currently using:
|
||||
//
|
||||
// .align PAGESIZE
|
||||
// .balign PAGESIZE
|
||||
// _tdata_start:
|
||||
// .tdata
|
||||
// _tdata_size = . - _tdata_start
|
||||
// .align PAGESIZE
|
||||
// .balign PAGESIZE
|
||||
// _tbss_start:
|
||||
// _tdata_start + _tbss_offset:
|
||||
// .tbss
|
||||
// .align TLS_ALIGNMENT
|
||||
// .balign TLS_ALIGNMENT
|
||||
// _tbss_size = . - _tbss_start
|
||||
// _tbss_end:
|
||||
// _tbss_start + _tbss_size:
|
||||
|
@ -219,5 +220,5 @@ textstartup void __enable_tls(void) {
|
|||
#endif
|
||||
|
||||
// we are now allowed to use tls
|
||||
__tls_enabled = true;
|
||||
__tls_enabled_set(true);
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ static dontinline textwindows bool ForkIo2(int64_t h, void *buf, size_t n,
|
|||
bool32 (*fn)(), const char *sf,
|
||||
bool ischild) {
|
||||
ssize_t rc = ForkIo(h, buf, n, fn);
|
||||
if (ischild) __tls_enabled = false; // prevent tls crash in kprintf
|
||||
if (ischild) __tls_enabled_set(false); // prevent tls crash in kprintf
|
||||
NTTRACE("%s(%ld, %p, %'zu) → %'zd% m", sf, h, buf, n, rc);
|
||||
return rc != -1;
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ textwindows void WinMainForked(void) {
|
|||
kStartTsc = savetsc;
|
||||
__threaded = false;
|
||||
__tls_index = 0;
|
||||
__tls_enabled = false;
|
||||
__tls_enabled_set(false);
|
||||
|
||||
// apply fixups and reapply memory protections
|
||||
_mmi.p = maps;
|
||||
|
@ -352,7 +352,7 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) {
|
|||
if (tib && _weaken(__set_tls) && _weaken(__morph_tls)) {
|
||||
_weaken(__set_tls)(tib);
|
||||
_weaken(__morph_tls)();
|
||||
__tls_enabled = true;
|
||||
__tls_enabled_set(true);
|
||||
}
|
||||
if (threaded && !__threaded && _weaken(__enable_threads)) {
|
||||
_weaken(__enable_threads)();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -38,27 +39,32 @@ int sys_fork(void) {
|
|||
|
||||
#elif defined(__aarch64__)
|
||||
|
||||
if (IsLinux()) {
|
||||
int flags = 17; // SIGCHLD;
|
||||
void *child_stack = 0;
|
||||
void *parent_tidptr = 0;
|
||||
void *newtls = 0;
|
||||
void *child_tidptr = 0;
|
||||
register long r0 asm("x0") = (long)flags;
|
||||
register long r1 asm("x1") = (long)child_stack;
|
||||
register long r2 asm("x2") = (long)parent_tidptr;
|
||||
register long r3 asm("x3") = (long)newtls;
|
||||
register long r4 asm("x4") = (long)child_tidptr;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(220), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)
|
||||
: "x8", "memory");
|
||||
return _sysret(res_x0);
|
||||
} else {
|
||||
return enosys();
|
||||
int flags = 17; // SIGCHLD
|
||||
void *child_stack = 0;
|
||||
void *parent_tidptr = 0;
|
||||
void *newtls = 0;
|
||||
void *child_tidptr = 0;
|
||||
register long r0 asm("x0") = (long)flags;
|
||||
register long r1 asm("x1") = (long)child_stack;
|
||||
register long r2 asm("x2") = (long)parent_tidptr;
|
||||
register long r3 asm("x3") = (long)newtls;
|
||||
register long r4 asm("x4") = (long)child_tidptr;
|
||||
register int res_x0 asm("x0");
|
||||
register int res_x1 asm("x1");
|
||||
asm volatile("mov\tx8,%2\n\t"
|
||||
"mov\tx16,%3\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0), "=r"(res_x1)
|
||||
: "i"(220), "i"(2), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)
|
||||
: "x8", "x16", "memory");
|
||||
if (IsXnu() && res_x0 != -1) {
|
||||
res_x0 &= res_x1 - 1;
|
||||
}
|
||||
return _sysret(res_x0);
|
||||
|
||||
#else
|
||||
|
||||
return enosys();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -18,15 +18,15 @@ extern const char v_ntsubsystem[] __attribute__((__weak__));
|
|||
extern const uintptr_t __fini_array_end[] __attribute__((__weak__));
|
||||
extern const uintptr_t __fini_array_start[] __attribute__((__weak__));
|
||||
|
||||
extern unsigned char _tdata_start[];
|
||||
extern unsigned char _tdata_end[];
|
||||
extern unsigned char _tdata_size[];
|
||||
extern unsigned char _tbss_start[];
|
||||
extern unsigned char _tbss_end[];
|
||||
extern unsigned char _tbss_size[];
|
||||
extern unsigned char _tbss_offset[];
|
||||
extern unsigned char _tls_size[];
|
||||
extern unsigned char _tls_content[];
|
||||
extern unsigned char _tdata_start[] __attribute__((__weak__));
|
||||
extern unsigned char _tdata_end[] __attribute__((__weak__));
|
||||
extern unsigned char _tdata_size[] __attribute__((__weak__));
|
||||
extern unsigned char _tbss_start[] __attribute__((__weak__));
|
||||
extern unsigned char _tbss_end[] __attribute__((__weak__));
|
||||
extern unsigned char _tbss_size[] __attribute__((__weak__));
|
||||
extern unsigned char _tbss_offset[] __attribute__((__weak__));
|
||||
extern unsigned char _tls_size[] __attribute__((__weak__));
|
||||
extern unsigned char _tls_content[] __attribute__((__weak__));
|
||||
|
||||
void _init(void) _Hide;
|
||||
void __morph_tls(void);
|
||||
|
@ -44,8 +44,7 @@ int GetDosEnviron(const char16_t *, char *, size_t, char **, size_t);
|
|||
bool __intercept_flag(int *, char *[], const char *);
|
||||
int sys_mprotect_nt(void *, size_t, int) _Hide;
|
||||
int __inflate(void *, size_t, const void *, size_t);
|
||||
noasan void *_Mmap(void *addr, size_t size, int prot, int flags, int fd,
|
||||
int64_t off) _Hide;
|
||||
noasan void *_Mmap(void *, size_t, int, int, int, int64_t) _Hide;
|
||||
noasan int _Munmap(char *, size_t) _Hide;
|
||||
void InitializeFileDescriptors(void);
|
||||
void __on_arithmetic_overflow(void);
|
||||
|
|
|
@ -126,18 +126,16 @@ forceinline pureconst bool IsOldStack(const void *x) {
|
|||
/* openbsd uses 4mb stack by default */
|
||||
/* freebsd uses 512mb stack by default */
|
||||
/* most systems use 8mb stack by default */
|
||||
size_t foss_stack_size = 4ul * 1024 * 1024;
|
||||
uintptr_t top = ROUNDUP(__oldstack, FRAMESIZE);
|
||||
uintptr_t bot = top - foss_stack_size;
|
||||
uintptr_t old = ROUNDDOWN(__oldstack, foss_stack_size);
|
||||
size_t foss_stack_size = 1ul * 1024 * 1024;
|
||||
uintptr_t top = ROUNDUP(__oldstack + 1, foss_stack_size);
|
||||
uintptr_t bot = ROUNDDOWN(__oldstack, foss_stack_size);
|
||||
return bot <= (uintptr_t)x && (uintptr_t)x < top;
|
||||
}
|
||||
|
||||
forceinline pureconst bool IsOldStackFrame(int x) {
|
||||
size_t foss_stack_size = 4ul * 1024 * 1024;
|
||||
uintptr_t top = ROUNDUP(__oldstack, FRAMESIZE);
|
||||
uintptr_t bot = top - foss_stack_size;
|
||||
uintptr_t old = ROUNDDOWN(__oldstack, foss_stack_size);
|
||||
size_t foss_stack_size = 1ul * 1024 * 1024;
|
||||
uintptr_t top = ROUNDUP(__oldstack + 1, foss_stack_size);
|
||||
uintptr_t bot = ROUNDDOWN(__oldstack, foss_stack_size);
|
||||
return (int)(bot >> 16) <= x && x <= (int)((top >> 16) - 1);
|
||||
}
|
||||
|
||||
|
@ -151,7 +149,7 @@ forceinline pureconst bool OverlapsImageSpace(const void *p, size_t n) {
|
|||
if (n) {
|
||||
BegA = p;
|
||||
EndA = BegA + (n - 1);
|
||||
BegB = _base;
|
||||
BegB = __executable_start;
|
||||
EndB = _end - 1;
|
||||
return MAX(BegA, BegB) < MIN(EndA, EndB);
|
||||
} else {
|
||||
|
|
|
@ -129,8 +129,8 @@ privileged void __morph_begin(sigset_t *save) {
|
|||
#else
|
||||
__morph_sigprocmask(SIG_BLOCK, &ss, save);
|
||||
#endif
|
||||
__morph_mprotect(_base, __privileged_addr - _base, PROT_READ | PROT_WRITE,
|
||||
kNtPageWritecopy);
|
||||
__morph_mprotect(__executable_start, __privileged_addr - __executable_start,
|
||||
PROT_READ | PROT_WRITE, kNtPageWritecopy);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,8 +140,8 @@ privileged void __morph_end(sigset_t *save) {
|
|||
int ax;
|
||||
long dx;
|
||||
bool cf;
|
||||
__morph_mprotect(_base, __privileged_addr - _base, PROT_READ | PROT_EXEC,
|
||||
kNtPageExecuteRead);
|
||||
__morph_mprotect(__executable_start, __privileged_addr - __executable_start,
|
||||
PROT_READ | PROT_EXEC, kNtPageExecuteRead);
|
||||
#ifdef __x86_64__
|
||||
if (IsOpenbsd()) {
|
||||
asm volatile(CFLAG_ASM("syscall")
|
||||
|
@ -153,7 +153,7 @@ privileged void __morph_end(sigset_t *save) {
|
|||
asm volatile("mov\t$8,%%r10d\n\t"
|
||||
"syscall"
|
||||
: "=a"(ax), "=d"(dx)
|
||||
: "0"(__NR_sigprocmask), "D"(SIG_SETMASK), "S"(save), "1"(0)
|
||||
: "0"(__NR_sigprocmask), "D"(SIG_SETMASK), "S"(save), "1"(0L)
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory", "cc");
|
||||
_npassert(!ax);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "ape/sections.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/morph.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
@ -44,7 +45,7 @@ privileged void __morph_tls(void) {
|
|||
// We check `_tls_content` which is generated by the linker script
|
||||
// since it lets us determine ahead of time if _Thread_local vars
|
||||
// have actually been linked into this program.
|
||||
if ((intptr_t)_tls_content && (IsWindows() || IsXnu())) {
|
||||
if (IsWindows() || IsXnu()) {
|
||||
int n;
|
||||
uint64_t w;
|
||||
sigset_t mask;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
// Loads all pages from program image into memory.
|
||||
_peekall:
|
||||
.leafprologue
|
||||
ezlea _base,si
|
||||
ezlea __executable_start,si
|
||||
ezlea _etext,cx
|
||||
add $0x1000,%rsi
|
||||
0: xor (%rsi),%eax
|
||||
|
@ -39,3 +39,7 @@ _peekall:
|
|||
jb 0b
|
||||
.leafepilogue
|
||||
.endfn _peekall,globl
|
||||
|
||||
.weak __executable_start
|
||||
.weak _etext
|
||||
.weak _end
|
||||
|
|
|
@ -233,7 +233,7 @@ textstartup void __printargs(const char *prologue) {
|
|||
"mov\t%%ebx,%1\n\t"
|
||||
"pop\t%%rbx"
|
||||
: "=a"(eax), "=rm"(ebx), "=c"(ecx), "=d"(edx)
|
||||
: "0"(0x40000000), "2"(0));
|
||||
: "0"(0x40000000), "2"(0L));
|
||||
PRINT(" Running inside %.4s%.4s%.4s (eax=%#x)", &ebx, &ecx, &edx, eax);
|
||||
}
|
||||
CPUID4_ITERATE(i, {
|
||||
|
@ -272,9 +272,8 @@ textstartup void __printargs(const char *prologue) {
|
|||
if (X86_HAVE(LA57)) kprintf(" LA57");
|
||||
if (X86_HAVE(FSGSBASE)) kprintf(" FSGSBASE");
|
||||
#elif defined(__aarch64__)
|
||||
PRINT(" AARCH64\n");
|
||||
PRINT(" AARCH64");
|
||||
#endif
|
||||
kprintf("\n");
|
||||
|
||||
PRINT("");
|
||||
PRINT("FILE DESCRIPTORS");
|
||||
|
@ -366,21 +365,33 @@ textstartup void __printargs(const char *prologue) {
|
|||
|
||||
PRINT("");
|
||||
PRINT("RESOURCE LIMITS");
|
||||
for (i = 0; i < RLIM_NLIMITS; ++i) {
|
||||
for (gotsome = i = 0; i < RLIM_NLIMITS; ++i) {
|
||||
if (!getrlimit(i, &rlim)) {
|
||||
char buf[20];
|
||||
if (rlim.rlim_cur == RLIM_INFINITY) rlim.rlim_cur = -1;
|
||||
if (rlim.rlim_max == RLIM_INFINITY) rlim.rlim_max = -1;
|
||||
PRINT(" ☼ %-20s %,16ld %,16ld", (DescribeRlimitName)(buf, i),
|
||||
rlim.rlim_cur, rlim.rlim_max);
|
||||
gotsome = true;
|
||||
}
|
||||
}
|
||||
if (!gotsome) {
|
||||
PRINT(" ☼ %s", "none");
|
||||
}
|
||||
|
||||
PRINT("");
|
||||
PRINT("STACK");
|
||||
size_t foss_stack_size = 4ul * 1024 * 1024;
|
||||
PRINT(" ☼ %p __oldstack top", ROUNDUP(__oldstack + 1, foss_stack_size));
|
||||
PRINT(" ☼ %p __oldstack ptr", __oldstack);
|
||||
PRINT(" ☼ %p __oldstack bot", ROUNDDOWN(__oldstack, foss_stack_size));
|
||||
PRINT(" ☼ %p __builtin_frame_address(0)", __builtin_frame_address(0));
|
||||
|
||||
PRINT("");
|
||||
PRINT("ARGUMENTS (%p)", __argv);
|
||||
if (*__argv) {
|
||||
for (i = 0; i < __argc; ++i) {
|
||||
PRINT(" ☼ %s", __argv[i]);
|
||||
PRINT(" ☼ %p %s", __argv[i], __argv[i]);
|
||||
}
|
||||
} else {
|
||||
PRINT(" none");
|
||||
|
@ -390,7 +401,7 @@ textstartup void __printargs(const char *prologue) {
|
|||
PRINT("ENVIRONMENT (%p)", __envp);
|
||||
if (*__envp) {
|
||||
for (env = __envp; *env; ++env) {
|
||||
PRINT(" ☼ %s", *env);
|
||||
PRINT(" ☼ %p %s", *env, *env);
|
||||
}
|
||||
} else {
|
||||
PRINT(" none");
|
||||
|
@ -403,9 +414,9 @@ textstartup void __printargs(const char *prologue) {
|
|||
for (auxp = __auxv; *auxp; auxp += 2) {
|
||||
if ((auxinfo = DescribeAuxv(auxp[0]))) {
|
||||
ksnprintf(u.path, sizeof(u.path), auxinfo->fmt, auxp[1]);
|
||||
PRINT(" ☼ %16s[%4ld] = %s", auxinfo->name, auxp[0], u.path);
|
||||
PRINT(" ☼ %p %16s[%4ld] = %s", auxp, auxinfo->name, auxp[0], u.path);
|
||||
} else {
|
||||
PRINT(" ☼ %16s[%4ld] = %014p", "unknown", auxp[0], auxp[1]);
|
||||
PRINT(" ☼ %p %16s[%4ld] = %014p", auxp, "unknown", auxp[0], auxp[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,9 @@ $(LIBC_RUNTIME_A).pkg: \
|
|||
# asan and ubsan can be function traced
|
||||
# we can't use function tracing because:
|
||||
# this is the function tracing runtime
|
||||
o/$(MODE)/libc/runtime/cosmo2.o: private \
|
||||
OVERRIDE_CFLAGS += -O0
|
||||
|
||||
o/$(MODE)/libc/runtime/ftracer.o: private \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-x-no-pg \
|
||||
|
@ -114,6 +117,13 @@ o//libc/runtime/opensymboltable.greg.o: private \
|
|||
OVERRIDE_CFLAGS += \
|
||||
-Os
|
||||
|
||||
ifeq ($(ARCH), aarch64)
|
||||
o/$(MODE)/libc/runtime/mmap.o \
|
||||
o/$(MODE)/libc/runtime/enable_tls.o: private \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-mcmodel=large
|
||||
endif
|
||||
|
||||
# these assembly files are safe to build on aarch64
|
||||
o/$(MODE)/libc/runtime/init.o: libc/runtime/init.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
|
|
@ -18,11 +18,13 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nexgen32e/msr.internal.h"
|
||||
#include "libc/nt/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#include "libc/thread/tls2.h"
|
||||
|
||||
int sys_set_tls();
|
||||
|
||||
|
@ -59,6 +61,9 @@ textstartup void __set_tls(struct CosmoTib *tib) {
|
|||
"d"((uint32_t)(val >> 32)));
|
||||
}
|
||||
#else
|
||||
asm volatile("msr\ttpidr_el0,%0" : /* no outputs */ : "r"(tib));
|
||||
asm volatile("mov\tx28,%0" : /* no outputs */ : "r"(tib));
|
||||
if (!IsXnu()) {
|
||||
asm volatile("msr\ttpidr_el0,%0" : /* no outputs */ : "r"(tib));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
54
libc/runtime/syslib.internal.h
Normal file
54
libc/runtime/syslib.internal.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_RUNTIME_SYSLIB_H_
|
||||
#define COSMOPOLITAN_LIBC_RUNTIME_SYSLIB_H_
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24)
|
||||
#define SYSLIB_VERSION 0
|
||||
|
||||
struct Syslib {
|
||||
int magic;
|
||||
int version;
|
||||
void (*exit)(int) wontreturn;
|
||||
long (*fork)(void);
|
||||
long (*read)(int, void *, size_t);
|
||||
long (*pread)(int, void *, size_t, int64_t);
|
||||
long (*readv)(int, const struct iovec *, int);
|
||||
long (*write)(int, const void *, size_t);
|
||||
long (*pwrite)(int, const void *, size_t, int64_t);
|
||||
long (*writev)(int, const struct iovec *, int);
|
||||
long (*openat)(int, const char *, int, ...);
|
||||
long (*pipe)(int[2]);
|
||||
long (*close)(int);
|
||||
long (*clock_gettime)(int, struct timespec *);
|
||||
long (*nanosleep)(const struct timespec *, struct timespec *);
|
||||
long (*mmap)(void *, size_t, int, int, int, int64_t);
|
||||
long (*sigaction)(int, const struct sigaction *restrict,
|
||||
struct sigaction *restrict);
|
||||
int (*pthread_jit_write_protect_supported_np)(void);
|
||||
void (*pthread_jit_write_protect_np)(int);
|
||||
void (*sys_icache_invalidate)(void *, size_t);
|
||||
pthread_t (*pthread_self)(void);
|
||||
int (*pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *),
|
||||
void *);
|
||||
int (*pthread_detach)(pthread_t);
|
||||
int (*pthread_join)(pthread_t, void **);
|
||||
void (*pthread_exit)(void *);
|
||||
int (*pthread_kill)(pthread_t, int);
|
||||
int (*pthread_sigmask)(int, const sigset_t *restrict, sigset_t *restrict);
|
||||
int (*pthread_setname_np)(const char *);
|
||||
int (*pthread_key_create)(pthread_key_t *, void (*)(void *));
|
||||
int (*pthread_setspecific)(pthread_key_t, const void *);
|
||||
void *(*pthread_getspecific)(pthread_key_t);
|
||||
};
|
||||
|
||||
extern struct Syslib *__syslib;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_RUNTIME_SYSLIB_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue