mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 05:42:29 +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
|
@ -16,52 +16,18 @@ void __assert_fail(const char *, const char *, int) _Hide relegated;
|
|||
#define static_assert _Static_assert
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if !defined(TINY) && !defined(MODE_DBG)
|
||||
/**
|
||||
* Specifies expression can't possibly be false.
|
||||
*
|
||||
* This macro uses the `notpossible` keyword and is intended for things
|
||||
* like systems integration, where we know for a fact that something is
|
||||
* never going to happen, but there's no proof. So we don't want to add
|
||||
* extra bloat for filenames and line numbers, since `ShowCrashReports`
|
||||
* can print a backtrace if we just embed the UD2 instruction to crash.
|
||||
* That's useful for systems code, for the following reason. Invariants
|
||||
* make sense with _unassert() since they usually get placed at the top
|
||||
* of functions. But if you used _unassert() to test a system call does
|
||||
* not fail, then check happens at the end of your function usually and
|
||||
* is therefore likely to result in a failure condition where execution
|
||||
* falls through into a different function, which is shocking to debug.
|
||||
*
|
||||
* In `MODE=tiny` these assertions are redefined as undefined behavior.
|
||||
*/
|
||||
#define _npassert(x) \
|
||||
({ \
|
||||
if (__builtin_expect(!(x), 0)) { \
|
||||
notpossible; \
|
||||
} \
|
||||
(void)0; \
|
||||
#ifndef NDEBUG
|
||||
#define _unassert(x) __assert_macro(x, #x)
|
||||
#define _npassert(x) __assert_macro(x, #x)
|
||||
#define __assert_macro(x, s) \
|
||||
({ \
|
||||
if (__builtin_expect(!(x), 0)) { \
|
||||
__assert_fail(s, __FILE__, __LINE__); \
|
||||
notpossible; \
|
||||
} \
|
||||
(void)0; \
|
||||
})
|
||||
#else
|
||||
#define _npassert(x) _unassert(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
/**
|
||||
* Specifies expression being false is undefined behavior.
|
||||
*
|
||||
* This is a good way to tell the compiler about your invariants, which
|
||||
* leads to smaller faster programs. The expression is never removed by
|
||||
* the preprocessor so it's recommended that it be free of side-effects
|
||||
* if you intend for it to be removed. At the same time, this guarantee
|
||||
* makes this assertion useful for things like system calls, since they
|
||||
* won't be removed by `NDEBUG` mode.
|
||||
*
|
||||
* If this assertion fails, the worst possible things can happen unless
|
||||
* you've built your binary in `MODE=dbg` since UBSAN is the only thing
|
||||
* that's capable of debugging this macro.
|
||||
*/
|
||||
#define _unassert(x) \
|
||||
({ \
|
||||
if (__builtin_expect(!(x), 0)) { \
|
||||
|
@ -69,6 +35,16 @@ void __assert_fail(const char *, const char *, int) _Hide relegated;
|
|||
} \
|
||||
(void)0; \
|
||||
})
|
||||
#define _npassert(x) \
|
||||
({ \
|
||||
if (__builtin_expect(!(x), 0)) { \
|
||||
notpossible; \
|
||||
} \
|
||||
(void)0; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
|
|
|
@ -134,7 +134,7 @@ static bool __sig_deliver(bool restartable, int sig, int si_code,
|
|||
}
|
||||
|
||||
// handover control to user
|
||||
((sigaction_f)(_base + rva))(sig, infop, ctx);
|
||||
((sigaction_f)(__executable_start + rva))(sig, infop, ctx);
|
||||
|
||||
if ((~flags & SA_NODEFER) && (~flags & SA_RESETHAND)) {
|
||||
// it's now safe to reenter the signal so we need to restore it.
|
||||
|
|
|
@ -188,6 +188,10 @@ o/$(MODE)/libc/calls/unveil.o: private \
|
|||
OVERRIDE_CFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
||||
ifeq ($(ARCH), aarch64)
|
||||
o/$(MODE)/libc/calls/sigaction.o: private OVERRIDE_CFLAGS += -mcmodel=large
|
||||
endif
|
||||
|
||||
# we want -Os because:
|
||||
# it makes a big difference
|
||||
# we need pic because:
|
||||
|
|
26
libc/calls/err.c
Normal file
26
libc/calls/err.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 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/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
|
||||
extern _Thread_local int hog;
|
||||
|
||||
int dog(void) {
|
||||
return hog;
|
||||
}
|
|
@ -24,7 +24,6 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/likely.h"
|
||||
#include "libc/intrin/promises.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
|
|
|
@ -63,7 +63,7 @@ textstartup noasan void InitializeMetalFile(void) {
|
|||
* The zipos code will automatically arrange to do this. Alternatively,
|
||||
* user code can STATIC_YOINK this symbol.
|
||||
*/
|
||||
size_t size = ROUNDUP(_ezip - _base, 4096);
|
||||
size_t size = ROUNDUP(_ezip - __executable_start, 4096);
|
||||
void *copied_base;
|
||||
struct DirectMap dm;
|
||||
dm = sys_mmap_metal(NULL, size, PROT_READ | PROT_WRITE,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "ape/sections.internal.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/blocksigs.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
|
@ -168,9 +169,11 @@ static int __sigaction(int sig, const struct sigaction *act,
|
|||
rva = (int32_t)(intptr_t)SIG_DFL;
|
||||
} else if ((intptr_t)act->sa_handler < kSigactionMinRva) {
|
||||
rva = (int)(intptr_t)act->sa_handler;
|
||||
} else if ((intptr_t)act->sa_handler >= (intptr_t)&_base + kSigactionMinRva &&
|
||||
(intptr_t)act->sa_handler < (intptr_t)&_base + INT_MAX) {
|
||||
rva = (int)((uintptr_t)act->sa_handler - (uintptr_t)&_base);
|
||||
} else if ((intptr_t)act->sa_handler >=
|
||||
(intptr_t)&__executable_start + kSigactionMinRva &&
|
||||
(intptr_t)act->sa_handler <
|
||||
(intptr_t)&__executable_start + INT_MAX) {
|
||||
rva = (int)((uintptr_t)act->sa_handler - (uintptr_t)&__executable_start);
|
||||
} else {
|
||||
return efault();
|
||||
}
|
||||
|
@ -249,8 +252,9 @@ static int __sigaction(int sig, const struct sigaction *act,
|
|||
if (oldact) {
|
||||
oldrva = __sighandrvas[sig];
|
||||
oldact->sa_sigaction =
|
||||
(sigaction_f)(oldrva < kSigactionMinRva ? oldrva
|
||||
: (intptr_t)&_base + oldrva);
|
||||
(sigaction_f)(oldrva < kSigactionMinRva
|
||||
? oldrva
|
||||
: (intptr_t)&__executable_start + oldrva);
|
||||
}
|
||||
if (act) {
|
||||
__sighandrvas[sig] = rva;
|
||||
|
|
|
@ -45,7 +45,7 @@ privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
|
|||
if (rva >= kSigactionMinRva) {
|
||||
flags = __sighandflags[sig & (NSIG - 1)];
|
||||
if (~flags & SA_SIGINFO) {
|
||||
((sigaction_f)(_base + rva))(sig, 0, 0);
|
||||
((sigaction_f)(__executable_start + rva))(sig, 0, 0);
|
||||
} else {
|
||||
__repstosb(&g, 0, sizeof(g));
|
||||
g.uc.uc_mcontext.fpregs = &g.uc.__fpustate;
|
||||
|
@ -78,7 +78,7 @@ privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
|
|||
g.uc.uc_mcontext.trapno = ctx->uc_mcontext.mc_trapno;
|
||||
__repmovsb(&g.uc.__fpustate, &ctx->uc_mcontext.mc_fpstate, 512);
|
||||
__siginfo2cosmo(&g.si, (void *)freebsdinfo);
|
||||
((sigaction_f)(_base + rva))(sig, &g.si, &g.uc);
|
||||
((sigaction_f)(__executable_start + rva))(sig, &g.si, &g.uc);
|
||||
ctx->uc_stack.ss_sp = g.uc.uc_stack.ss_sp;
|
||||
ctx->uc_stack.ss_size = g.uc.uc_stack.ss_size;
|
||||
ctx->uc_stack.ss_flags = g.uc.uc_stack.ss_flags;
|
||||
|
|
|
@ -44,7 +44,7 @@ privileged void __sigenter_wsl(int sig, struct siginfo *info, ucontext_t *ctx) {
|
|||
memcpy(ctx->__fpustate.st + i, &nan, 16);
|
||||
}
|
||||
}
|
||||
((sigaction_f)(_base + rva))(sig, info, ctx);
|
||||
((sigaction_f)(__executable_start + rva))(sig, info, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ privileged void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
|||
if (rva >= kSigactionMinRva) {
|
||||
flags = __sighandflags[sig & (NSIG - 1)];
|
||||
if (~flags & SA_SIGINFO) {
|
||||
((sigaction_f)(_base + rva))(sig, 0, 0);
|
||||
((sigaction_f)(__executable_start + rva))(sig, 0, 0);
|
||||
} else {
|
||||
__repstosb(&uc, 0, sizeof(uc));
|
||||
__siginfo2cosmo(&si2, (void *)si);
|
||||
|
@ -75,7 +75,7 @@ privileged void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
|||
uc.uc_mcontext.rip = ctx->uc_mcontext.rip;
|
||||
uc.uc_mcontext.rsp = ctx->uc_mcontext.rsp;
|
||||
*uc.uc_mcontext.fpregs = ctx->uc_mcontext.__fpregs;
|
||||
((sigaction_f)(_base + rva))(sig, &si2, &uc);
|
||||
((sigaction_f)(__executable_start + rva))(sig, &si2, &uc);
|
||||
ctx->uc_stack.ss_sp = uc.uc_stack.ss_sp;
|
||||
ctx->uc_stack.ss_size = uc.uc_stack.ss_size;
|
||||
ctx->uc_stack.ss_flags = uc.uc_stack.ss_flags;
|
||||
|
|
|
@ -45,7 +45,7 @@ privileged void __sigenter_openbsd(int sig, struct siginfo_openbsd *openbsdinfo,
|
|||
if (rva >= kSigactionMinRva) {
|
||||
flags = __sighandflags[sig & (NSIG - 1)];
|
||||
if (~flags & SA_SIGINFO) {
|
||||
((sigaction_f)(_base + rva))(sig, 0, 0);
|
||||
((sigaction_f)(__executable_start + rva))(sig, 0, 0);
|
||||
} else {
|
||||
__repstosb(&g.uc, 0, sizeof(g.uc));
|
||||
__siginfo2cosmo(&g.si, (void *)openbsdinfo);
|
||||
|
@ -76,7 +76,7 @@ privileged void __sigenter_openbsd(int sig, struct siginfo_openbsd *openbsdinfo,
|
|||
if (ctx->sc_fpstate) {
|
||||
*g.uc.uc_mcontext.fpregs = *ctx->sc_fpstate;
|
||||
}
|
||||
((sigaction_f)(_base + rva))(sig, &g.si, &g.uc);
|
||||
((sigaction_f)(__executable_start + rva))(sig, &g.si, &g.uc);
|
||||
ctx->sc_mask = g.uc.uc_sigmask.__bits[0];
|
||||
ctx->sc_rdi = g.uc.uc_mcontext.rdi;
|
||||
ctx->sc_rsi = g.uc.uc_mcontext.rsi;
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
/**
|
||||
* @fileoverview XNU kernel callback normalization.
|
||||
|
@ -345,10 +344,37 @@ struct __darwin_mcontext_avx512_64_full {
|
|||
struct __darwin_x86_avx512_state64 __fs;
|
||||
};
|
||||
|
||||
struct __darwin_arm_exception_state64 {
|
||||
uint64_t far;
|
||||
uint32_t esr;
|
||||
uint32_t exception;
|
||||
};
|
||||
|
||||
struct __darwin_arm_thread_state64 {
|
||||
uint64_t __x[29];
|
||||
uint64_t __fp;
|
||||
uint64_t __lr;
|
||||
uint64_t __sp;
|
||||
uint64_t __pc;
|
||||
uint32_t __cpsr;
|
||||
uint32_t __pad;
|
||||
};
|
||||
|
||||
struct __darwin_arm_vfp_state {
|
||||
uint32_t __r[64];
|
||||
uint32_t __fpscr;
|
||||
};
|
||||
|
||||
struct __darwin_mcontext64 {
|
||||
#ifdef __x86_64__
|
||||
struct __darwin_x86_exception_state64 __es;
|
||||
struct __darwin_x86_thread_state64 __ss;
|
||||
struct __darwin_x86_float_state64 __fs;
|
||||
#elif defined(__aarch64__)
|
||||
struct __darwin_arm_exception_state64 __es;
|
||||
struct __darwin_arm_thread_state64 __ss;
|
||||
struct __darwin_arm_vfp_state __fs;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct __darwin_ucontext {
|
||||
|
@ -360,6 +386,8 @@ struct __darwin_ucontext {
|
|||
struct __darwin_mcontext64 *uc_mcontext;
|
||||
};
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
static privileged void xnuexceptionstate2linux(
|
||||
mcontext_t *mc, struct __darwin_x86_exception_state64 *xnues) {
|
||||
mc->trapno = xnues->__trapno;
|
||||
|
@ -455,6 +483,8 @@ static privileged void linuxssefpustate2xnu(
|
|||
CopyFpXmmRegs(&xnufs->__fpu_stmm0, fs->st);
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
|
||||
struct siginfo_xnu *xnuinfo,
|
||||
struct __darwin_ucontext *xnuctx) {
|
||||
|
@ -468,15 +498,17 @@ privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
|
|||
if (rva >= kSigactionMinRva) {
|
||||
flags = __sighandflags[sig & (NSIG - 1)];
|
||||
if (~flags & SA_SIGINFO) {
|
||||
((sigaction_f)(_base + rva))(sig, 0, 0);
|
||||
((sigaction_f)(__executable_start + rva))(sig, 0, 0);
|
||||
} else {
|
||||
__repstosb(&g, 0, sizeof(g));
|
||||
|
||||
if (xnuctx) {
|
||||
g.uc.uc_sigmask.__bits[0] = xnuctx->uc_sigmask;
|
||||
g.uc.uc_sigmask.__bits[1] = 0;
|
||||
g.uc.uc_stack.ss_sp = xnuctx->uc_stack.ss_sp;
|
||||
g.uc.uc_stack.ss_flags = xnuctx->uc_stack.ss_flags;
|
||||
g.uc.uc_stack.ss_size = xnuctx->uc_stack.ss_size;
|
||||
#ifdef __x86_64__
|
||||
g.uc.uc_mcontext.fpregs = &g.uc.__fpustate;
|
||||
if (xnuctx->uc_mcontext) {
|
||||
if (xnuctx->uc_mcsize >=
|
||||
|
@ -493,16 +525,24 @@ privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
|
|||
xnussefpustate2linux(&g.uc.__fpustate, &xnuctx->uc_mcontext->__fs);
|
||||
}
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
if (xnuctx->uc_mcontext) {
|
||||
memcpy(g.uc.uc_mcontext.regs, &xnuctx->uc_mcontext->__ss.__x, 33 * 8);
|
||||
}
|
||||
#endif /* __x86_64__ */
|
||||
}
|
||||
|
||||
if (xnuinfo) {
|
||||
__siginfo2cosmo(&g.si, (void *)xnuinfo);
|
||||
}
|
||||
((sigaction_f)(_base + rva))(sig, &g.si, &g.uc);
|
||||
((sigaction_f)(__executable_start + rva))(sig, &g.si, &g.uc);
|
||||
|
||||
if (xnuctx) {
|
||||
xnuctx->uc_stack.ss_sp = g.uc.uc_stack.ss_sp;
|
||||
xnuctx->uc_stack.ss_flags = g.uc.uc_stack.ss_flags;
|
||||
xnuctx->uc_stack.ss_size = g.uc.uc_stack.ss_size;
|
||||
xnuctx->uc_sigmask = g.uc.uc_sigmask.__bits[0];
|
||||
#ifdef __x86_64__
|
||||
if (xnuctx->uc_mcontext) {
|
||||
if (xnuctx->uc_mcsize >=
|
||||
sizeof(struct __darwin_x86_exception_state64)) {
|
||||
|
@ -519,14 +559,29 @@ privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
|
|||
linuxssefpustate2xnu(&xnuctx->uc_mcontext->__fs, &g.uc.__fpustate);
|
||||
}
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
if (xnuctx->uc_mcontext) {
|
||||
memcpy(&xnuctx->uc_mcontext->__ss.__x, g.uc.uc_mcontext.regs, 33 * 8);
|
||||
}
|
||||
#endif /* __x86_64__ */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
asm volatile("syscall"
|
||||
: "=a"(ax)
|
||||
: "0"(0x20000b8 /* sigreturn */), "D"(xnuctx), "S"(infostyle)
|
||||
: "rcx", "r11", "memory", "cc");
|
||||
#else
|
||||
register long r0 asm("x0") = (long)xnuctx;
|
||||
register long r1 asm("x1") = (long)infostyle;
|
||||
asm volatile("mov\tx16,%0\n\t"
|
||||
"svc\t0"
|
||||
: /* no outputs */
|
||||
: "i"(0x0b8 /* sigreturn */), "r"(r0), "r"(r1)
|
||||
: "x16", "memory");
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
notpossible;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,9 +17,27 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/sysv/consts/nr.h"
|
||||
|
||||
static inline unsigned sys_umask(unsigned newmask) {
|
||||
#ifdef __x86_64__
|
||||
unsigned res;
|
||||
asm volatile("syscall"
|
||||
: "=a"(res)
|
||||
: "0"(__NR_umask), "D"(newmask)
|
||||
: "memory", "cc");
|
||||
#elif defined(__aarch64__)
|
||||
// xnu m1 doesn't manage carry flag
|
||||
register long r0 asm("x0") = newmask;
|
||||
register long r8 asm("x8") = __NR_umask & 0x7ff;
|
||||
register long r16 asm("x16") = __NR_umask & 0x7ff;
|
||||
register unsigned res asm("x0");
|
||||
asm volatile("svc\t0" : "=r"(res) : "r"(r0), "r"(r8), "r"(r16) : "memory");
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets file mode creation mask.
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#define nlink_t uint64_t
|
||||
#elif defined(__aarch64__)
|
||||
#define blksize_t int32_t
|
||||
#define nlink_t uint32_t
|
||||
#define nlink_t uint32_t /* uint16_t on xnu */
|
||||
#endif
|
||||
|
||||
#define TIME_T_MAX __INT64_MAX__
|
||||
|
|
|
@ -128,6 +128,11 @@ _start:
|
|||
// setup backtraces
|
||||
mov x29,#0
|
||||
|
||||
// second arg shall be struct Syslib passed by ape-m1.c
|
||||
// used to talk to apple's authoritarian libraries
|
||||
// should be set to zero on other platforms
|
||||
mov x1,x15
|
||||
|
||||
// switch to c code
|
||||
bl cosmo
|
||||
.unreachable
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
*/
|
||||
#define SUPPORT_VECTOR 255
|
||||
#else
|
||||
#define SUPPORT_VECTOR _HOSTLINUX
|
||||
#define SUPPORT_VECTOR (_HOSTLINUX | _HOSTXNU)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -110,11 +110,11 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#ifdef __x86_64__
|
||||
extern const int __hostos;
|
||||
|
||||
#ifdef __x86_64__
|
||||
bool IsWsl1(void);
|
||||
#else
|
||||
#define __hostos _HOSTLINUX
|
||||
#define IsWsl1() false
|
||||
#endif
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __memchr_aarch64 memchr
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __memcmp_aarch64 memcmp
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#define __memcpy_aarch64_simd memcpy
|
||||
#define __memmove_aarch64_simd memmove
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __memrchr_aarch64 memrchr
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __memset_aarch64 memset
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __stpcpy_aarch64 stpcpy
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __strchr_aarch64 strchr
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __strchrnul_aarch64 strchrnul
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __strcmp_aarch64 strcmp
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __strcpy_aarch64 strcpy
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __strlen_aarch64 strlen
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __strncmp_aarch64 strncmp
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __strnlen_aarch64 strnlen
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define __strrchr_aarch64 strrchr
|
||||
|
||||
.ident "\n\
|
||||
.ident "\n\n\
|
||||
Optimized Routines (MIT License)\n\
|
||||
Copyright 2022 ARM Limited\n"
|
||||
.include "libc/disclaimer.inc"
|
||||
|
|
|
@ -412,7 +412,7 @@ static bool __asan_is_mapped(int x) {
|
|||
}
|
||||
|
||||
static bool __asan_is_image(const unsigned char *p) {
|
||||
return _base <= p && p < _end;
|
||||
return __executable_start <= p && p < _end;
|
||||
}
|
||||
|
||||
static bool __asan_exists(const void *x) {
|
||||
|
@ -823,7 +823,7 @@ static void __asan_report_memory_origin(const unsigned char *addr, int size,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (_base <= addr && addr < _end) {
|
||||
if (__executable_start <= addr && addr < _end) {
|
||||
__asan_report_memory_origin_image((intptr_t)addr, size);
|
||||
} else if (IsAutoFrame((intptr_t)addr >> 16)) {
|
||||
__asan_report_memory_origin_heap(addr, size);
|
||||
|
@ -898,7 +898,7 @@ dontdiscard static __asan_die_f *__asan_report(const void *addr, int size,
|
|||
}
|
||||
*p++ = '\n';
|
||||
}
|
||||
p = __asan_format_section(p, _base, _etext, ".text", addr);
|
||||
p = __asan_format_section(p, __executable_start, _etext, ".text", addr);
|
||||
p = __asan_format_section(p, _etext, _edata, ".data", addr);
|
||||
p = __asan_format_section(p, _end, _edata, ".bss", addr);
|
||||
__mmi_lock();
|
||||
|
@ -1487,7 +1487,7 @@ void __asan_init(int argc, char **argv, char **envp, intptr_t *auxv) {
|
|||
REQUIRE(dlmalloc_usable_size);
|
||||
}
|
||||
__asan_shadow_existing_mappings();
|
||||
__asan_map_shadow((uintptr_t)_base, _end - _base);
|
||||
__asan_map_shadow((uintptr_t)__executable_start, _end - __executable_start);
|
||||
__asan_map_shadow(0, 4096);
|
||||
__asan_poison(0, GUARDSIZE, kAsanNullPage);
|
||||
if (!IsWindows()) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/atomic.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
|
@ -38,7 +39,7 @@ relegated void __assert_fail(const char *expr, const char *file, int line) {
|
|||
owner = 0;
|
||||
me = sys_gettid();
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
|
||||
kprintf("%s:%d: assert(%s) failed (tid %d)\n", file, line, expr, me);
|
||||
kprintf("%s:%d: assert(%s) failed (tid %d) %m\n", file, line, expr, me);
|
||||
if (__vforked ||
|
||||
atomic_compare_exchange_strong_explicit(
|
||||
&once, &owner, me, memory_order_relaxed, memory_order_relaxed)) {
|
||||
|
|
|
@ -66,7 +66,7 @@ static const char *GetFrameName(int x) {
|
|||
sizeof(struct WinArgs) - 1) >>
|
||||
16))) {
|
||||
return "winargs";
|
||||
} else if ((int)((intptr_t)_base >> 16) <= x &&
|
||||
} else if ((int)((intptr_t)__executable_start >> 16) <= x &&
|
||||
x <= (int)(((intptr_t)_end - 1) >> 16)) {
|
||||
return "image";
|
||||
} else {
|
||||
|
|
|
@ -62,9 +62,11 @@ struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd,
|
|||
register long res_x0 asm("x0");
|
||||
long res;
|
||||
asm volatile("mov\tx8,%1\n\t"
|
||||
"mov\tx16,%2\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(222), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)
|
||||
: "i"(222), "i"(197), "r"(r0), "r"(r1), "r"(r2), "r"(r3),
|
||||
"r"(r4), "r"(r5)
|
||||
: "x8", "memory");
|
||||
res = res_x0;
|
||||
if ((unsigned long)res >= (unsigned long)-4095) {
|
||||
|
|
|
@ -68,10 +68,11 @@ wontreturn void _Exit(int exitcode) {
|
|||
#elif defined(__aarch64__)
|
||||
register long x0 asm("x0") = exitcode;
|
||||
asm volatile("mov\tx8,%0\n\t"
|
||||
"mov\tx16,%1\n\t"
|
||||
"svc\t0"
|
||||
: /* no outputs */
|
||||
: "i"(94), "r"(x0)
|
||||
: "x8", "memory");
|
||||
: "i"(94), "i"(1), "r"(x0)
|
||||
: "x8", "x16", "memory");
|
||||
notpossible;
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
|
|
|
@ -76,9 +76,10 @@ privileged wontreturn void _Exit1(int rc) {
|
|||
#elif defined(__aarch64__)
|
||||
register long r0 asm("x0") = rc;
|
||||
asm volatile("mov\tx8,%0\n\t"
|
||||
"mov\tx16,%1\n\t"
|
||||
"svc\t0"
|
||||
: /* no outputs */
|
||||
: "i"(93), "r"(r0)
|
||||
: "i"(93), "i"(0x169), "r"(r0)
|
||||
: "x8", "memory");
|
||||
notpossible;
|
||||
#else
|
||||
|
|
|
@ -130,11 +130,13 @@ privileged static inline bool kiskernelpointer(const void *p) {
|
|||
}
|
||||
|
||||
privileged static inline bool kistextpointer(const void *p) {
|
||||
return _base <= (const unsigned char *)p && (const unsigned char *)p < _etext;
|
||||
return __executable_start <= (const unsigned char *)p &&
|
||||
(const unsigned char *)p < _etext;
|
||||
}
|
||||
|
||||
privileged static inline bool kisimagepointer(const void *p) {
|
||||
return _base <= (const unsigned char *)p && (const unsigned char *)p < _end;
|
||||
return __executable_start <= (const unsigned char *)p &&
|
||||
(const unsigned char *)p < _end;
|
||||
}
|
||||
|
||||
privileged static inline bool kischarmisaligned(const char *p, signed char t) {
|
||||
|
@ -224,11 +226,12 @@ privileged static void klog(const char *b, size_t n) {
|
|||
register long r0 asm("x0") = (long)2;
|
||||
register long r1 asm("x1") = (long)b;
|
||||
register long r2 asm("x2") = (long)n;
|
||||
register long r8 asm("x8") = (long)__NR_write;
|
||||
register long r8 asm("x8") = (long)__NR_write & 0x7ff;
|
||||
register long r16 asm("x16") = (long)__NR_write & 0x7ff;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "r"(r0), "r"(r1), "r"(r2), "r"(r8)
|
||||
: "r"(r0), "r"(r1), "r"(r2), "r"(r8), "r"(r16)
|
||||
: "memory");
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#define _NOPL_PROLOGUE(SECTION) \
|
||||
".section \".sort.rodata." SECTION ".1" \
|
||||
"\",\"aG\",@progbits,\"" SECTION "\",comdat\n\t" \
|
||||
".align\t4\n\t" \
|
||||
".balign\t4\n\t" \
|
||||
".type\t\"" SECTION "_start\",@object\n\t" \
|
||||
".globl\t\"" SECTION "_start\"\n\t" \
|
||||
".equ\t\"" SECTION "_start\",.\n\t" \
|
||||
|
@ -29,7 +29,7 @@
|
|||
#define _NOPL_EPILOGUE(SECTION) \
|
||||
".section \".sort.rodata." SECTION ".3" \
|
||||
"\",\"aG\",@progbits,\"" SECTION "\",comdat\n\t" \
|
||||
".align\t4\n\t" \
|
||||
".balign\t4\n\t" \
|
||||
".type\"" SECTION "_end\",@object\n\t" \
|
||||
".globl\t\"" SECTION "_end\"\n\t" \
|
||||
".equ\t\"" SECTION "_end\",.\n\t" \
|
||||
|
@ -40,7 +40,7 @@
|
|||
asm volatile(_NOPL_PROLOGUE(SECTION) /* */ \
|
||||
_NOPL_EPILOGUE(SECTION) /* */ \
|
||||
".section \".sort.rodata." SECTION ".2\",\"a\",@progbits\n\t" \
|
||||
".align\t4\n\t" \
|
||||
".balign\t4\n\t" \
|
||||
".long\t353f-%a1\n\t" \
|
||||
".previous\n353:\t" \
|
||||
"nopl\t%a0" \
|
||||
|
@ -57,7 +57,7 @@
|
|||
asm volatile(_NOPL_PROLOGUE(SECTION) /* */ \
|
||||
_NOPL_EPILOGUE(SECTION) /* */ \
|
||||
".section \".sort.rodata." SECTION ".2\",\"a\",@progbits\n\t" \
|
||||
".align\t4\n\t" \
|
||||
".balign\t4\n\t" \
|
||||
".long\t353f-%a2\n\t" \
|
||||
".previous\n353:\t" \
|
||||
"nopl\t%a1" \
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#include "libc/thread/tls2.h"
|
||||
|
||||
privileged void __stracef(const char *fmt, ...) {
|
||||
|
|
|
@ -65,9 +65,10 @@ privileged int sys_gettid(void) {
|
|||
#elif defined(__aarch64__)
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n\t"
|
||||
"mov\tx16,%2\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(178)
|
||||
: "i"(178), "i"(186)
|
||||
: "x8", "memory");
|
||||
return res_x0;
|
||||
#else
|
||||
|
|
|
@ -12,7 +12,7 @@ COSMOPOLITAN_C_START_
|
|||
bool Cond; \
|
||||
struct countbranch *Info; \
|
||||
asm(".section .rodata.str1.1,\"aMS\",@progbits,1\n\t" \
|
||||
".align\t1\n" \
|
||||
".balign\t1\n" \
|
||||
"31338:\t" \
|
||||
".asciz\t" xs "\n" \
|
||||
"31339:\t" \
|
||||
|
@ -24,7 +24,7 @@ COSMOPOLITAN_C_START_
|
|||
"nopl\tcountbranch_data(%%rip)\n\t" \
|
||||
".previous\n\t" \
|
||||
".section .sort.data.countbranch.2,\"a\",@progbits\n\t" \
|
||||
".align\t8\n31337:\t" \
|
||||
".balign\t8\n31337:\t" \
|
||||
".quad\t0\n\t" \
|
||||
".quad\t0\n\t" \
|
||||
".quad\t31338b\n\t" \
|
||||
|
|
|
@ -40,7 +40,7 @@ COSMOPOLITAN_C_START_
|
|||
t2_ = stop(); \
|
||||
TiCkS = t2_ >= t1_ ? t2_ - t1_ : ~t1_ + t2_ + 1; \
|
||||
asm(".section .rodata.str1.1,\"aMS\",@progbits,1\n\t" \
|
||||
".align\t1\n" \
|
||||
".balign\t1\n" \
|
||||
"31340:\t.asciz\t" file "\n\t" \
|
||||
"31338:\t.asciz\t" code "\n" \
|
||||
"31332:\t.asciz\t" macro "\n" \
|
||||
|
@ -49,7 +49,7 @@ COSMOPOLITAN_C_START_
|
|||
"nopl\tcountexpr_data(%%rip)\n\t" \
|
||||
".previous\n\t" \
|
||||
".section .sort.data.countexpr.2,\"a\",@progbits\n\t" \
|
||||
".align\t8\n31337:\t" \
|
||||
".balign\t8\n31337:\t" \
|
||||
".quad\t" #line "\n\t" \
|
||||
".quad\t31340b\n\t" \
|
||||
".quad\t31338b\n\t" \
|
||||
|
|
|
@ -19,12 +19,13 @@ forceinline long __sysv_exit(long rc) {
|
|||
: "memory", "cc");
|
||||
#elif defined(__aarch64__)
|
||||
register long r0 asm("x0") = rc;
|
||||
register long r8 asm("x8") = __NR_exit_group;
|
||||
register long r8 asm("x8") = __NR_exit_group & 0x7ff;
|
||||
register long r16 asm("x16") = __NR_exit_group & 0x7ff;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("svc\t0" : "=r"(res_x0) : "r"(r0), "r"(r8) : "memory");
|
||||
asm volatile("svc\t0" : "=r"(res_x0) : "r"(r0), "r"(r8), "r"(r16) : "memory");
|
||||
ax = res_x0;
|
||||
#else
|
||||
ax = syscall(__NR_exit_group, rc);
|
||||
ax = syscall(__NR_exit_group & 0x7ff, rc);
|
||||
#endif
|
||||
return ax;
|
||||
}
|
||||
|
@ -38,16 +39,17 @@ forceinline int __sysv_close(long fd) {
|
|||
: "rdx", "memory", "cc");
|
||||
#elif defined(__aarch64__)
|
||||
register long r0 asm("x0") = fd;
|
||||
register long r8 asm("x8") = __NR_close;
|
||||
register long r8 asm("x8") = __NR_close & 0x7ff;
|
||||
register long r16 asm("x16") = __NR_close & 0x7ff;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "r"(r0), "r"(r8)
|
||||
: "r"(r0), "r"(r8), "r"(r16)
|
||||
: "memory");
|
||||
ax = res_x0;
|
||||
#else
|
||||
ax = syscall(__NR_close, fd);
|
||||
ax = syscall(__NR_close & 0x7ff, fd);
|
||||
#endif
|
||||
return ax;
|
||||
}
|
||||
|
@ -64,15 +66,16 @@ forceinline int __sysv_open(const char *path, long flags, long mode) {
|
|||
register long r1 asm("x1") = (long)path;
|
||||
register long r2 asm("x2") = (long)flags;
|
||||
register long r3 asm("x3") = (long)mode;
|
||||
register long r8 asm("x8") = (long)__NR_open;
|
||||
register long r8 asm("x8") = (long)__NR_open & 0x7ff;
|
||||
register long r16 asm("x16") = (long)__NR_open & 0x7ff;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r8)
|
||||
: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r8), "r"(r16)
|
||||
: "memory");
|
||||
ax = res_x0;
|
||||
#else
|
||||
ax = syscall(__NR_open, path, flags, mode);
|
||||
ax = syscall(__NR_open & 0x7ff, path, flags, mode);
|
||||
#endif
|
||||
return ax;
|
||||
}
|
||||
|
@ -88,15 +91,16 @@ forceinline long __sysv_read(long fd, void *data, unsigned long size) {
|
|||
register long r0 asm("x0") = (long)fd;
|
||||
register long r1 asm("x1") = (long)data;
|
||||
register long r2 asm("x2") = (long)size;
|
||||
register long r8 asm("x8") = (long)__NR_read;
|
||||
register long r8 asm("x8") = (long)__NR_read & 0x7ff;
|
||||
register long r16 asm("x16") = (long)__NR_read & 0x7ff;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "r"(r0), "r"(r1), "r"(r2), "r"(r8)
|
||||
: "r"(r0), "r"(r1), "r"(r2), "r"(r8), "r"(r16)
|
||||
: "memory");
|
||||
ax = res_x0;
|
||||
#else
|
||||
ax = syscall(__NR_read, fd, data, size);
|
||||
ax = syscall(__NR_read & 0x7ff, fd, data, size);
|
||||
#endif
|
||||
return ax;
|
||||
}
|
||||
|
@ -112,15 +116,16 @@ forceinline long __sysv_write(long fd, const void *data, unsigned long size) {
|
|||
register long r0 asm("x0") = (long)fd;
|
||||
register long r1 asm("x1") = (long)data;
|
||||
register long r2 asm("x2") = (long)size;
|
||||
register long r8 asm("x8") = (long)__NR_write;
|
||||
register long r8 asm("x8") = (long)__NR_write & 0x7ff;
|
||||
register long r16 asm("x16") = (long)__NR_write & 0x7ff;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(64), "r"(r0), "r"(r1), "r"(r2), "r"(r8)
|
||||
: "i"(64), "r"(r0), "r"(r1), "r"(r2), "r"(r8), "r"(r16)
|
||||
: "memory");
|
||||
ax = res_x0;
|
||||
#else
|
||||
ax = syscall(__NR_write, fd, data, size);
|
||||
ax = syscall(__NR_write & 0x7ff, fd, data, size);
|
||||
#endif
|
||||
return ax;
|
||||
}
|
||||
|
@ -136,15 +141,16 @@ forceinline long __sysv_mprotect(void *addr, size_t size, long prot) {
|
|||
register long r0 asm("x0") = (long)addr;
|
||||
register long r1 asm("x1") = (long)size;
|
||||
register long r2 asm("x2") = (long)prot;
|
||||
register long r8 asm("x8") = (long)__NR_mprotect;
|
||||
register long r8 asm("x8") = (long)__NR_mprotect & 0x7ff;
|
||||
register long r16 asm("x16") = (long)__NR_mprotect & 0x7ff;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "r"(r0), "r"(r1), "r"(r2), "r"(r8)
|
||||
: "r"(r0), "r"(r1), "r"(r2), "r"(r8), "r"(r16)
|
||||
: "memory");
|
||||
ax = res_x0;
|
||||
#else
|
||||
ax = syscall(__NR_mprotect, addr, size, prot);
|
||||
ax = syscall(__NR_mprotect & 0x7ff, addr, size, prot);
|
||||
#endif
|
||||
return ax;
|
||||
}
|
||||
|
@ -157,12 +163,13 @@ forceinline int __sysv_getpid(void) {
|
|||
: "0"(__NR_getpid)
|
||||
: "rdx", "memory", "cc");
|
||||
#elif defined(__aarch64__)
|
||||
register long r8 asm("x8") = (long)__NR_getpid;
|
||||
register long r8 asm("x8") = (long)__NR_getpid & 0x7ff;
|
||||
register long r16 asm("x16") = (long)__NR_getpid & 0x7ff;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("svc\t0" : "=r"(res_x0) : "r"(r8) : "memory");
|
||||
asm volatile("svc\t0" : "=r"(res_x0) : "r"(r8), "r"(r16) : "memory");
|
||||
ax = res_x0;
|
||||
#else
|
||||
ax = syscall(__NR_getpid);
|
||||
ax = syscall(__NR_getpid & 0x7ff);
|
||||
#endif
|
||||
return ax;
|
||||
}
|
||||
|
|
|
@ -317,7 +317,7 @@ relegated void __oncrash_amd64(int sig, struct siginfo *si, void *arg) {
|
|||
// RestoreDefaultCrashSignalHandlers();
|
||||
gdbpid = AttachDebugger(
|
||||
((sig == SIGTRAP || sig == SIGQUIT) &&
|
||||
(rip >= (intptr_t)&_base && rip < (intptr_t)&_etext))
|
||||
(rip >= (intptr_t)&__executable_start && rip < (intptr_t)&_etext))
|
||||
? rip
|
||||
: 0);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ struct Buffer {
|
|||
};
|
||||
|
||||
static bool IsCode(uintptr_t p) {
|
||||
return _base <= (uint8_t *)p && (uint8_t *)p < _etext;
|
||||
return __executable_start <= (uint8_t *)p && (uint8_t *)p < _etext;
|
||||
}
|
||||
|
||||
static void Append(struct Buffer *b, const char *fmt, ...) {
|
||||
|
@ -97,8 +97,9 @@ static const char *ColorRegister(int r) {
|
|||
case 25: // saved
|
||||
case 26: // saved
|
||||
case 27: // saved
|
||||
case 28: // saved
|
||||
return MAGENTA;
|
||||
case 18: // platform register
|
||||
case 28: // our tls register
|
||||
case 29: // frame pointer
|
||||
case 30: // return pointer
|
||||
case 31: // stack pointer
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
// @note therefore no section relative addressing
|
||||
.macro .rodata.str1.1
|
||||
.section .rodata.str1.1,"aMS",@progbits,1
|
||||
.align 1
|
||||
.balign 1
|
||||
.endm
|
||||
|
||||
// Locates unreferenced code invulnerable to --gc-sections.
|
||||
|
@ -150,6 +150,12 @@
|
|||
.weak \canonical
|
||||
.endm
|
||||
|
||||
#ifdef __aarch64__
|
||||
.macro jmp dest:req
|
||||
b \dest
|
||||
.endm
|
||||
#endif
|
||||
|
||||
// Pulls unrelated module into linkage.
|
||||
//
|
||||
// In order for this technique to work with --gc-sections, another
|
||||
|
@ -195,31 +201,31 @@
|
|||
// @note therefore no section relative addressing
|
||||
.macro .rodata.cst4
|
||||
.section .rodata.cst4,"aM",@progbits,4
|
||||
.align 4
|
||||
.balign 4
|
||||
.endm
|
||||
.macro .rodata.cst8
|
||||
.section .rodata.cst8,"aM",@progbits,8
|
||||
.align 8
|
||||
.balign 8
|
||||
.endm
|
||||
.macro .rodata.cst16
|
||||
.section .rodata.cst16,"aM",@progbits,16
|
||||
.align 16
|
||||
.balign 16
|
||||
.endm
|
||||
.macro .rodata.cst32
|
||||
.section .rodata.cst32,"aM",@progbits,32
|
||||
.align 32
|
||||
.balign 32
|
||||
.endm
|
||||
.macro .rodata.cst64
|
||||
.section .rodata.cst64,"aM",@progbits,64
|
||||
.align 64
|
||||
.balign 64
|
||||
.endm
|
||||
.macro .tdata
|
||||
.section .tdata,"awT",@progbits
|
||||
.align 4
|
||||
.balign 4
|
||||
.endm
|
||||
.macro .tbss
|
||||
.section .tdata,"awT",@nobits
|
||||
.align 4
|
||||
.balign 4
|
||||
.endm
|
||||
|
||||
// Loads address of errno into %rcx
|
||||
|
@ -242,11 +248,11 @@
|
|||
// @see libc/runtime/_init.S
|
||||
.macro .initro number:req name:req
|
||||
.section ".initro.\number\().\name","a",@progbits
|
||||
.align 8
|
||||
.balign 8
|
||||
.endm
|
||||
.macro .initbss number:req name:req
|
||||
.section ".piro.bss.init.2.\number\().\name","aw",@nobits
|
||||
.align 8
|
||||
.balign 8
|
||||
.endm
|
||||
.macro .init.start number:req name:req
|
||||
.section ".init.\number\().\name","ax",@progbits
|
||||
|
|
|
@ -66,7 +66,7 @@ kHalfCache3:
|
|||
#else
|
||||
|
||||
.rodata
|
||||
.align 8
|
||||
.balign 8
|
||||
kHalfCache3:
|
||||
.quad 4 * 1024 * 1024
|
||||
.endobj kHalfCache3,globl
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
int __threaded;
|
||||
|
||||
#ifdef __x86_64__
|
||||
bool __tls_enabled;
|
||||
#endif
|
||||
|
||||
unsigned __tls_index;
|
||||
|
|
|
@ -38,7 +38,8 @@ __zip_end:
|
|||
.short v_zip_records // number of records on disk
|
||||
.short v_zip_records // records
|
||||
.long v_zip_cdirsize // size of central directory
|
||||
.long RVA(__zip_start) // central directory offset
|
||||
.weak v_zip_cdoffset
|
||||
.long v_zip_cdoffset // central directory offset
|
||||
.short v_zip_commentsize // comment size
|
||||
.endobj __zip_end,globl,hidden
|
||||
.weak v_zip_records
|
||||
|
|
|
@ -48,8 +48,8 @@ kNtdllProcRvas:
|
|||
0: lodsq
|
||||
test %rax,%rax
|
||||
jz 1f
|
||||
.weak _base
|
||||
lea _base(%rax),%rdx
|
||||
.weak __executable_start
|
||||
lea __executable_start(%rax),%rdx
|
||||
mov %r12,%rcx
|
||||
call *__imp_GetProcAddress(%rip)
|
||||
test %rax,%rax
|
||||
|
|
|
@ -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_ */
|
|
@ -57,6 +57,10 @@ $(LIBC_SOCK_A).pkg: \
|
|||
$(LIBC_SOCK_A_OBJS) \
|
||||
$(foreach x,$(LIBC_SOCK_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
# these assembly files are safe to build on aarch64
|
||||
o/$(MODE)/libc/sock/sys_sendfile_xnu.o: libc/sock/sys_sendfile_xnu.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
||||
LIBC_SOCK_LIBS = $(foreach x,$(LIBC_SOCK_ARTIFACTS),$($(x)))
|
||||
LIBC_SOCK_SRCS = $(foreach x,$(LIBC_SOCK_ARTIFACTS),$($(x)_SRCS))
|
||||
LIBC_SOCK_HDRS = $(foreach x,$(LIBC_SOCK_ARTIFACTS),$($(x)_HDRS))
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
// $OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
strlcat (ISC)\\n\
|
||||
OpenBSD Strings (ISC)\\n\
|
||||
Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org> │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
|
@ -16,27 +16,43 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
// clang-format off
|
||||
// $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
OpenBSD Strings (ISC)\\n\
|
||||
Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/**
|
||||
* Copies string, the BSD way.
|
||||
*
|
||||
* @param d is buffer which needn't be initialized
|
||||
* @param s is a NUL-terminated string
|
||||
* @param n is byte capacity of d
|
||||
* @return strlen(s)
|
||||
* @note d and s can't overlap
|
||||
* @note we prefer memccpy()
|
||||
* Copy string src to buffer `dst` of size `dsize`. At most `dsize-1`
|
||||
* chars will be copied. Always NUL terminates (unless `dsize == 0`).
|
||||
* Returns `strlen(src)`; if `retval >= dsize`, truncation occurred.
|
||||
*/
|
||||
size_t strlcpy(char *d, const char *s, size_t n) {
|
||||
size_t slen, actual;
|
||||
slen = strlen(s);
|
||||
if (n) {
|
||||
actual = MIN(n - 1, slen);
|
||||
memcpy(d, s, actual);
|
||||
d[actual] = '\0';
|
||||
}
|
||||
return slen;
|
||||
size_t
|
||||
strlcpy(char *dst, const char *src, size_t dsize)
|
||||
{
|
||||
const char *osrc = src;
|
||||
size_t nleft = dsize;
|
||||
|
||||
/* Copy as many bytes as will fit. */
|
||||
if (nleft != 0) {
|
||||
while (--nleft != 0) {
|
||||
if ((*dst++ = *src++) == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src. */
|
||||
if (nleft == 0) {
|
||||
if (dsize != 0)
|
||||
*dst = '\0'; /* NUL-terminate dst */
|
||||
while (*src++)
|
||||
;
|
||||
}
|
||||
|
||||
return(src - osrc - 1); /* count does not include NUL */
|
||||
}
|
||||
|
|
117
libc/stubs/ld.S
117
libc/stubs/ld.S
|
@ -1,117 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
|
||||
// Traditional executable boundaries defined by linker.
|
||||
// @see man etext
|
||||
_etext = 0
|
||||
_edata = 0
|
||||
_end = 0
|
||||
|
||||
// Cosmopolitan executable boundaries defined by linker script.
|
||||
// @see libc/elf/elf.lds
|
||||
// @see ape/ape.lds
|
||||
_base = 0
|
||||
ape_xlm = 0
|
||||
_ehead = 0
|
||||
_ezip = 0
|
||||
_ereal = 0
|
||||
__privileged_start = 0
|
||||
__privileged_end = 0
|
||||
__privileged_addr = 0
|
||||
__privileged_size = 0
|
||||
__test_start = 0
|
||||
__ro = 0
|
||||
__relo_start = 0
|
||||
__relo_end = 0
|
||||
__data_start = 0
|
||||
__data_end = 0
|
||||
__bss_start = 0
|
||||
__bss_end = 0
|
||||
|
||||
// Thread local boundaries defined by linker script
|
||||
// @see ape/ape.lds
|
||||
_tdata_start = 0
|
||||
_tdata_end = 0
|
||||
_tdata_size = 0
|
||||
_tbss_start = 0
|
||||
_tbss_end = 0
|
||||
_tbss_offset = 0
|
||||
_tbss_size = 0
|
||||
_tls_size = 0
|
||||
_tls_content = 0
|
||||
|
||||
.globl _base
|
||||
.globl ape_xlm
|
||||
.globl __relo_start
|
||||
.globl __relo_end
|
||||
.globl __privileged_size
|
||||
.globl __privileged_addr
|
||||
.globl __privileged_start
|
||||
.globl __privileged_end
|
||||
.globl __ro
|
||||
.globl __test_start
|
||||
.globl _edata
|
||||
.globl _ehead
|
||||
.globl _end
|
||||
.globl _ezip
|
||||
.globl _ereal
|
||||
.globl _etext
|
||||
.globl _tdata_start
|
||||
.globl _tdata_end
|
||||
.globl _tdata_size
|
||||
.globl _tbss_start
|
||||
.globl _tbss_end
|
||||
.globl _tbss_size
|
||||
.globl _tbss_offset
|
||||
.globl _tls_size
|
||||
.globl _tls_content
|
||||
.globl __data_start
|
||||
.globl __data_end
|
||||
.globl __bss_start
|
||||
.globl __bss_end
|
||||
|
||||
.weak _base
|
||||
.weak ape_xlm
|
||||
.weak __relo_start
|
||||
.weak __relo_end
|
||||
.weak __privileged_size
|
||||
.weak __privileged_addr
|
||||
.weak __privileged_start
|
||||
.weak __privileged_end
|
||||
.weak __ro
|
||||
.weak __test_start
|
||||
.weak _edata
|
||||
.weak _ehead
|
||||
.weak _end
|
||||
.weak _ezip
|
||||
.weak _ereal
|
||||
.weak _etext
|
||||
.weak _tdata_start
|
||||
.weak _tdata_end
|
||||
.weak _tdata_size
|
||||
.weak _tbss_start
|
||||
.weak _tbss_end
|
||||
.weak _tbss_size
|
||||
.weak _tls_size
|
||||
.weak _tls_content
|
||||
.weak _tbss_offset
|
||||
.weak __data_start
|
||||
.weak __data_end
|
||||
.weak __bss_start
|
||||
.weak __bss_end
|
|
@ -43,8 +43,6 @@ $(LIBC_STUBS_A).pkg: \
|
|||
$(foreach x,$(LIBC_STUBS_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
# these assembly files are safe to build on aarch64
|
||||
o/$(MODE)/libc/stubs/ld.o: libc/stubs/ld.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/stubs/abort.o: libc/stubs/abort.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __bsd_setegid,0xfff0b60b620b6fff,0xfff,globl,hidden
|
||||
.scall __bsd_setegid,0xfff0b60b620b6fff,4095,182,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __bsd_seteuid,0xfff0b70b720b7fff,0xfff,globl,hidden
|
||||
.scall __bsd_seteuid,0xfff0b70b720b7fff,4095,183,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_accept,0x81e81ea1d281e82b,0x0ca,globl,hidden
|
||||
.scall __sys_accept,0x81e81ea1d281e82b,202,30,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_accept4,0xfff85da1dffff920,0x0f2,globl,hidden
|
||||
.scall __sys_accept4,0xfff85da1dffff920,242,4095,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_bind,0x0680680682068031,0x0c8,globl,hidden
|
||||
.scall __sys_bind,0x0680680682068031,200,104,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_clock_nanosleep,0x9ddfff8f4ffff8e6,0x073,globl,hidden
|
||||
.scall __sys_clock_nanosleep,0x9ddfff8f4ffff8e6,115,4095,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_connect,0x862862862286282a,0x0cb,globl,hidden
|
||||
.scall __sys_connect,0x862862862286282a,203,98,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_dup3,0x1c6066fffffff124,0x018,globl,hidden
|
||||
.scall __sys_dup3,0x1c6066fffffff124,24,4095,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_execve,0x03b03b03b203b03b,0x0dd,globl,hidden
|
||||
.scall __sys_execve,0x03b03b03b203b03b,221,59,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_fcntl,0x05c05c05c205c048,0x019,globl,hidden
|
||||
.scall __sys_fcntl,0x05c05c05c205c048,25,92,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_fcntl_cp,0x85c85c85c285c848,0x019,globl,hidden
|
||||
.scall __sys_fcntl_cp,0x85c85c85c285c848,25,92,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_fork,0x0020020022002039,0xfff,globl,hidden
|
||||
.scall __sys_fork,0x0020020022002039,4095,2,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_fstat,0x1b80352272153005,0x050,globl,hidden
|
||||
.scall __sys_fstat,0x1b80352272153005,80,339,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_fstatat,0x1d202a22821d6106,0x04f,globl,hidden
|
||||
.scall __sys_fstatat,0x1d202a22821d6106,79,470,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_getpeername,0x01f01f08d201f034,0x0cd,globl,hidden
|
||||
.scall __sys_getpeername,0x01f01f08d201f034,205,31,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_getrusage,0x1bd0130752075062,0x0a5,globl,hidden
|
||||
.scall __sys_getrusage,0x1bd0130752075062,165,117,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_getsockname,0x0200200202020033,0x0cc,globl,hidden
|
||||
.scall __sys_getsockname,0x0200200202020033,204,32,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_gettid,0x13712b1b0101b0ba,0x0b2,globl,hidden
|
||||
.scall __sys_gettid,0x13712b1b0101b0ba,178,27,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_lstat,0x1b90280282154006,0xfff,globl,hidden
|
||||
.scall __sys_lstat,0x1b90280282154006,4095,340,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_mmap,0x0c50c51dd20c5009,0x0de,globl,hidden
|
||||
.scall __sys_mmap,0x0c50c51dd20c5009,222,197,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_mremap,0x19bffffffffff019,0x0d8,globl,hidden
|
||||
.scall __sys_mremap,0x19bffffffffff019,216,4095,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_munmap,0x049049049204900b,0x0d7,globl,hidden
|
||||
.scall __sys_munmap,0x049049049204900b,215,73,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_openat,0x9d49419f329cf901,0x038,globl,hidden
|
||||
.scall __sys_openat,0x9d49419f329cf901,56,463,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_openat_nc,0x1d41411f321d0101,0x038,globl,hidden
|
||||
.scall __sys_openat_nc,0x1d41411f321d0101,56,464,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_pipe,0x02a10721e202a016,0x03b,globl,hidden
|
||||
.scall __sys_pipe,0x02a10721e202a016,59,42,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_pipe2,0x1c506521effff125,0x03b,globl,hidden
|
||||
.scall __sys_pipe2,0x1c506521effff125,59,4095,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_poll,0x8d18fc8d128e6807,0xfff,globl,hidden
|
||||
.scall __sys_poll,0x8d18fc8d128e6807,4095,230,globl,hidden
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue