mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-26 14:28:30 +00:00
Get Fat Emacs working on Apple Silicon
This commit is contained in:
parent
3f9b39883f
commit
bf835de612
14 changed files with 294 additions and 144 deletions
135
ape/ape-m1.c
135
ape/ape-m1.c
|
@ -50,7 +50,7 @@ struct Syslib {
|
|||
void *);
|
||||
void (*pthread_exit)(void *);
|
||||
int (*pthread_kill)(pthread_t, int);
|
||||
int (*pthread_sigmask)(int, const sigset_t *restrict, sigset_t *restrict);
|
||||
int (*pthread_sigmask)(int, const sigset_t *, sigset_t *);
|
||||
int (*pthread_setname_np)(const char *);
|
||||
dispatch_semaphore_t (*dispatch_semaphore_create)(long);
|
||||
long (*dispatch_semaphore_signal)(dispatch_semaphore_t);
|
||||
|
@ -399,26 +399,24 @@ static char *Commandv(struct PathSearcher *ps, const char *name,
|
|||
static void pthread_jit_write_protect_np_workaround(int enabled) {
|
||||
int count_start = 8192;
|
||||
volatile int count = count_start;
|
||||
unsigned long *addr, *other, val, val2, reread = -1;
|
||||
unsigned long *addr, val, val2, reread = -1;
|
||||
addr = (unsigned long *)(!enabled ? _COMM_PAGE_APRR_WRITE_ENABLE
|
||||
: _COMM_PAGE_APRR_WRITE_DISABLE);
|
||||
other = (unsigned long *)(enabled ? _COMM_PAGE_APRR_WRITE_ENABLE
|
||||
: _COMM_PAGE_APRR_WRITE_DISABLE);
|
||||
switch (*(volatile unsigned char *)_COMM_PAGE_APRR_SUPPORT) {
|
||||
case 1:
|
||||
do {
|
||||
val = *addr;
|
||||
reread = -1;
|
||||
asm volatile("msr\tS3_4_c15_c2_7,%0\n"
|
||||
"isb\tsy\n"
|
||||
: /* no outputs */
|
||||
: "r"(val)
|
||||
: "memory");
|
||||
__asm__ volatile("msr\tS3_4_c15_c2_7,%0\n"
|
||||
"isb\tsy\n"
|
||||
: /* no outputs */
|
||||
: "r"(val)
|
||||
: "memory");
|
||||
val2 = *addr;
|
||||
asm volatile("mrs\t%0,S3_4_c15_c2_7\n"
|
||||
: "=r"(reread)
|
||||
: /* no inputs */
|
||||
: "memory");
|
||||
__asm__ volatile("mrs\t%0,S3_4_c15_c2_7\n"
|
||||
: "=r"(reread)
|
||||
: /* no inputs */
|
||||
: "memory");
|
||||
if (val2 == reread) {
|
||||
return;
|
||||
}
|
||||
|
@ -429,16 +427,16 @@ static void pthread_jit_write_protect_np_workaround(int enabled) {
|
|||
do {
|
||||
val = *addr;
|
||||
reread = -1;
|
||||
asm volatile("msr\tS3_6_c15_c1_5,%0\n"
|
||||
"isb\tsy\n"
|
||||
: /* no outputs */
|
||||
: "r"(val)
|
||||
: "memory");
|
||||
__asm__ volatile("msr\tS3_6_c15_c1_5,%0\n"
|
||||
"isb\tsy\n"
|
||||
: /* no outputs */
|
||||
: "r"(val)
|
||||
: "memory");
|
||||
val2 = *addr;
|
||||
asm volatile("mrs\t%0,S3_6_c15_c1_5\n"
|
||||
: "=r"(reread)
|
||||
: /* no inputs */
|
||||
: "memory");
|
||||
__asm__ volatile("mrs\t%0,S3_6_c15_c1_5\n"
|
||||
: "=r"(reread)
|
||||
: /* no inputs */
|
||||
: "memory");
|
||||
if (val2 == reread) {
|
||||
return;
|
||||
}
|
||||
|
@ -595,42 +593,42 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
|
|||
/* finish up */
|
||||
close(fd);
|
||||
|
||||
register long *x0 asm("x0") = sp;
|
||||
register struct Syslib *x15 asm("x15") = lib;
|
||||
register long x16 asm("x16") = e->e_entry;
|
||||
asm volatile("mov\tx1,#0\n\t"
|
||||
"mov\tx2,#0\n\t"
|
||||
"mov\tx3,#0\n\t"
|
||||
"mov\tx4,#0\n\t"
|
||||
"mov\tx5,#0\n\t"
|
||||
"mov\tx6,#0\n\t"
|
||||
"mov\tx7,#0\n\t"
|
||||
"mov\tx8,#0\n\t"
|
||||
"mov\tx9,#0\n\t"
|
||||
"mov\tx10,#0\n\t"
|
||||
"mov\tx11,#0\n\t"
|
||||
"mov\tx12,#0\n\t"
|
||||
"mov\tx13,#0\n\t"
|
||||
"mov\tx14,#0\n\t"
|
||||
"mov\tx17,#0\n\t"
|
||||
"mov\tx19,#0\n\t"
|
||||
"mov\tx20,#0\n\t"
|
||||
"mov\tx21,#0\n\t"
|
||||
"mov\tx22,#0\n\t"
|
||||
"mov\tx23,#0\n\t"
|
||||
"mov\tx24,#0\n\t"
|
||||
"mov\tx25,#0\n\t"
|
||||
"mov\tx26,#0\n\t"
|
||||
"mov\tx27,#0\n\t"
|
||||
"mov\tx28,#0\n\t"
|
||||
"mov\tx29,#0\n\t"
|
||||
"mov\tx30,#0\n\t"
|
||||
"mov\tsp,x0\n\t"
|
||||
"mov\tx0,#0\n\t"
|
||||
"br\tx16"
|
||||
: /* no outputs */
|
||||
: "r"(x0), "r"(x15), "r"(x16)
|
||||
: "memory");
|
||||
register long *x0 __asm__("x0") = sp;
|
||||
register struct Syslib *x15 __asm__("x15") = lib;
|
||||
register long x16 __asm__("x16") = e->e_entry;
|
||||
__asm__ volatile("mov\tx1,#0\n\t"
|
||||
"mov\tx2,#0\n\t"
|
||||
"mov\tx3,#0\n\t"
|
||||
"mov\tx4,#0\n\t"
|
||||
"mov\tx5,#0\n\t"
|
||||
"mov\tx6,#0\n\t"
|
||||
"mov\tx7,#0\n\t"
|
||||
"mov\tx8,#0\n\t"
|
||||
"mov\tx9,#0\n\t"
|
||||
"mov\tx10,#0\n\t"
|
||||
"mov\tx11,#0\n\t"
|
||||
"mov\tx12,#0\n\t"
|
||||
"mov\tx13,#0\n\t"
|
||||
"mov\tx14,#0\n\t"
|
||||
"mov\tx17,#0\n\t"
|
||||
"mov\tx19,#0\n\t"
|
||||
"mov\tx20,#0\n\t"
|
||||
"mov\tx21,#0\n\t"
|
||||
"mov\tx22,#0\n\t"
|
||||
"mov\tx23,#0\n\t"
|
||||
"mov\tx24,#0\n\t"
|
||||
"mov\tx25,#0\n\t"
|
||||
"mov\tx26,#0\n\t"
|
||||
"mov\tx27,#0\n\t"
|
||||
"mov\tx28,#0\n\t"
|
||||
"mov\tx29,#0\n\t"
|
||||
"mov\tx30,#0\n\t"
|
||||
"mov\tsp,x0\n\t"
|
||||
"mov\tx0,#0\n\t"
|
||||
"br\tx16"
|
||||
: /* no outputs */
|
||||
: "r"(x0), "r"(x15), "r"(x16)
|
||||
: "memory");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
@ -769,7 +767,7 @@ static long sys_pipe(int pfds[2]) {
|
|||
}
|
||||
|
||||
static long sys_clock_gettime(int clock, struct timespec *ts) {
|
||||
return sysret(clock_gettime(clock, ts));
|
||||
return sysret(clock_gettime((clockid_t)clock, ts));
|
||||
}
|
||||
|
||||
static long sys_nanosleep(const struct timespec *req, struct timespec *rem) {
|
||||
|
@ -782,17 +780,16 @@ static long sys_mmap(void *addr, size_t size, int prot, int flags, int fd,
|
|||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
long z;
|
||||
void *map;
|
||||
int c, i, n, fd, rc;
|
||||
unsigned i;
|
||||
int c, n, fd, rc;
|
||||
struct ApeLoader *M;
|
||||
long *sp, *sp2, *auxv;
|
||||
union ElfEhdrBuf *ebuf;
|
||||
char *p, *pe, *tp, *exe, *prog, *execfn;
|
||||
char *p, *pe, *exe, *prog, *execfn;
|
||||
|
||||
/* allocate loader memory in program's arg block */
|
||||
n = sizeof(struct ApeLoader);
|
||||
M = __builtin_alloca(n);
|
||||
M = (struct ApeLoader *)__builtin_alloca(n);
|
||||
|
||||
/* expose apple libs */
|
||||
M->lib.magic = SYSLIB_MAGIC;
|
||||
|
@ -839,7 +836,7 @@ int main(int argc, char **argv, char **envp) {
|
|||
} else if (argc < 2) {
|
||||
Emit("usage: ape PROG [ARGV1,ARGV2,...]\n"
|
||||
" ape - PROG [ARGV0,ARGV1,...]\n"
|
||||
"actually portable executable loader silicon 1.6\n"
|
||||
"actually portable executable loader silicon 1.7\n"
|
||||
"copyright 2023 justine alexandra roberts tunney\n"
|
||||
"https://justine.lol/ape.html\n");
|
||||
_exit(1);
|
||||
|
@ -853,7 +850,7 @@ int main(int argc, char **argv, char **envp) {
|
|||
system v abi aligns this on a 16-byte boundary
|
||||
grows down the alloc by poking the guard pages */
|
||||
n = (auxv - sp + AUXV_WORDS + 1) * sizeof(long);
|
||||
sp2 = __builtin_alloca(n);
|
||||
sp2 = (long *)__builtin_alloca(n);
|
||||
if ((long)sp2 & 15) ++sp2;
|
||||
for (; n > 0; n -= pagesz) {
|
||||
((char *)sp2)[n - 1] = 0;
|
||||
|
@ -866,7 +863,7 @@ int main(int argc, char **argv, char **envp) {
|
|||
|
||||
/* allocate ephemeral memory for reading file */
|
||||
n = sizeof(union ElfEhdrBuf);
|
||||
ebuf = __builtin_alloca(n);
|
||||
ebuf = (union ElfEhdrBuf *)__builtin_alloca(n);
|
||||
for (; n > 0; n -= pagesz) {
|
||||
((char *)ebuf)[n - 1] = 0;
|
||||
}
|
||||
|
@ -886,9 +883,7 @@ int main(int argc, char **argv, char **envp) {
|
|||
/* resolve argv[0] to reflect path search */
|
||||
if ((argc > 0 && *prog != '/' && *exe == '/' && !StrCmp(prog, argv[0])) ||
|
||||
!StrCmp(BaseName(prog), argv[0])) {
|
||||
tp -= (n = StrLen(exe) + 1);
|
||||
MemMove(tp, exe, n);
|
||||
argv[0] = tp;
|
||||
argv[0] = exe;
|
||||
}
|
||||
|
||||
/* generate some hard random data */
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "libc/runtime/pc.internal.h"
|
||||
#include "ape/ape.internal.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#include "ape/ape.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
#define USE_SYMBOL_HACK 1
|
||||
|
@ -610,7 +611,9 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
|
|||
// extract the loader into a temp folder, and use it to
|
||||
// load the APE without modifying it.
|
||||
.ascii "[ x\"$1\" != x--assimilate ] && {\n"
|
||||
.ascii "t=\"${TMPDIR:-${HOME:-.}}/.ape-1.7\"\n"
|
||||
.ascii "t=\"${TMPDIR:-${HOME:-.}}/.ape-"
|
||||
.ascii APE_VERSION_STR
|
||||
.ascii "\"\n"
|
||||
.ascii "[ -x \"$t\" ] || {\n"
|
||||
.ascii "mkdir -p \"${t%/*}\" &&\n"
|
||||
.ascii "dd if=\"$o\" of=\"$t.$$\" skip="
|
||||
|
@ -818,7 +821,7 @@ ape.ident:
|
|||
.long 1
|
||||
1: .asciz "APE"
|
||||
2: .balign 4
|
||||
3: .long 107000000
|
||||
3: .long APE_VERSION_NOTE
|
||||
4: .size ape.ident,.-ape.ident
|
||||
.type ape.ident,@object
|
||||
.previous
|
||||
|
|
13
ape/ape.h
Normal file
13
ape/ape.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef COSMOPOLITAN_APE_APE_H_
|
||||
#define COSMOPOLITAN_APE_APE_H_
|
||||
|
||||
#define APE_VERSION_MAJOR 1
|
||||
#define APE_VERSION_MINOR 7
|
||||
#define APE_VERSION_STR APE_VERSION_STR_(APE_VERSION_MAJOR, APE_VERSION_MINOR)
|
||||
#define APE_VERSION_NOTE APE_VERSION_NOTE_(APE_VERSION_MAJOR, APE_VERSION_MINOR)
|
||||
|
||||
#define APE_VERSION_STR__(x, y) #x "." #y
|
||||
#define APE_VERSION_STR_(x, y) APE_VERSION_STR__(x, y)
|
||||
#define APE_VERSION_NOTE_(x, y) (100000000 * (x) + 1000000 * (y))
|
||||
|
||||
#endif /* COSMOPOLITAN_APE_APE_H_ */
|
|
@ -88,7 +88,7 @@ o/$(MODE)/ape/ape.elf.dbg: \
|
|||
o/$(MODE)/ape/systemcall.o
|
||||
@$(COMPILE) -ALINK.elf $(LD) $(APE_LOADER_LDFLAGS) -o $@ $(patsubst %.lds,-T %.lds,$^)
|
||||
|
||||
o/$(MODE)/ape/loader.o: ape/loader.c
|
||||
o/$(MODE)/ape/loader.o: ape/loader.c ape/ape.h
|
||||
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=1 -g $(APE_LOADER_FLAGS)
|
||||
o/$(MODE)/ape/start.o: ape/start.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
@ -130,6 +130,8 @@ APE_LOADER_FLAGS = \
|
|||
-iquote. \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-Werror \
|
||||
-pedantic-errors \
|
||||
-fpie \
|
||||
-Os \
|
||||
-ffreestanding \
|
||||
|
@ -153,6 +155,7 @@ o/ape/idata.inc: \
|
|||
|
||||
o/$(MODE)/ape/ape-no-modify-self.o: \
|
||||
ape/ape.S \
|
||||
ape/ape.h \
|
||||
ape/macros.internal.h \
|
||||
ape/notice.inc \
|
||||
ape/relocations.h \
|
||||
|
@ -183,6 +186,7 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
|
|||
|
||||
o/$(MODE)/ape/ape-copy-self.o: \
|
||||
ape/ape.S \
|
||||
ape/ape.h \
|
||||
ape/macros.internal.h \
|
||||
ape/notice.inc \
|
||||
ape/relocations.h \
|
||||
|
|
29
ape/loader.c
29
ape/loader.c
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/ape.h"
|
||||
|
||||
/**
|
||||
* @fileoverview APE Loader for GNU/Systemd/XNU/FreeBSD/NetBSD/OpenBSD
|
||||
|
@ -104,6 +105,12 @@
|
|||
#define IsAarch64() 0
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C extern "C"
|
||||
#else
|
||||
#define EXTERN_C
|
||||
#endif
|
||||
|
||||
#define O_RDONLY 0
|
||||
#define PROT_NONE 0
|
||||
#define PROT_READ 1
|
||||
|
@ -213,8 +220,8 @@ struct ApeLoader {
|
|||
char path[1024];
|
||||
};
|
||||
|
||||
long SystemCall(long, long, long, long, long, long, long, int);
|
||||
void Launch(void *, long, void *, int) __attribute__((__noreturn__));
|
||||
EXTERN_C long SystemCall(long, long, long, long, long, long, long, int);
|
||||
EXTERN_C void Launch(void *, long, void *, int) __attribute__((__noreturn__));
|
||||
|
||||
extern char __executable_start[];
|
||||
extern char _end[];
|
||||
|
@ -882,11 +889,11 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
|
|||
Spawn(os, exe, fd, sp, pagesz, e, p);
|
||||
}
|
||||
|
||||
static __attribute__((__noreturn__)) void ShowUsage(int os, int fd, int rc) {
|
||||
__attribute__((__noreturn__)) static void ShowUsage(int os, int fd, int rc) {
|
||||
Print(os, fd,
|
||||
"NAME\n"
|
||||
"\n"
|
||||
" actually portable executable loader version 1.7\n"
|
||||
" actually portable executable loader version " APE_VERSION_STR "\n"
|
||||
" copyright 2023 justine alexandra roberts tunney\n"
|
||||
" https://justine.lol/ape.html\n"
|
||||
"\n"
|
||||
|
@ -904,15 +911,17 @@ static __attribute__((__noreturn__)) void ShowUsage(int os, int fd, int rc) {
|
|||
Exit(rc, os);
|
||||
}
|
||||
|
||||
__attribute__((__noreturn__)) void ApeLoader(long di, long *sp, char dl) {
|
||||
EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
|
||||
char dl) {
|
||||
int rc, n;
|
||||
unsigned i;
|
||||
const char *ape;
|
||||
int c, fd, os, argc;
|
||||
struct ApeLoader *M;
|
||||
unsigned long pagesz;
|
||||
union ElfEhdrBuf *ebuf;
|
||||
long *auxv, *ap, *endp, *sp2;
|
||||
char *p, *pe, *exe, *ape, *prog, **argv, **envp;
|
||||
char *p, *pe, *exe, *prog, **argv, **envp;
|
||||
|
||||
(void)Utox;
|
||||
|
||||
|
@ -999,13 +1008,13 @@ __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, char dl) {
|
|||
|
||||
/* allocate loader memory in program's arg block */
|
||||
n = sizeof(struct ApeLoader);
|
||||
M = __builtin_alloca(n);
|
||||
M = (struct ApeLoader *)__builtin_alloca(n);
|
||||
|
||||
/* create new bottom of stack for spawned program
|
||||
system v abi aligns this on a 16-byte boundary
|
||||
grows down the alloc by poking the guard pages */
|
||||
n = (endp - sp + 1) * sizeof(long);
|
||||
sp2 = __builtin_alloca(n);
|
||||
sp2 = (long *)__builtin_alloca(n);
|
||||
if ((long)sp2 & 15) ++sp2;
|
||||
for (; n > 0; n -= pagesz) {
|
||||
((char *)sp2)[n - 1] = 0;
|
||||
|
@ -1013,12 +1022,12 @@ __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, char dl) {
|
|||
MemMove(sp2, sp, (endp - sp) * sizeof(long));
|
||||
argv = (char **)(sp2 + 1);
|
||||
envp = (char **)(sp2 + 1 + argc + 1);
|
||||
auxv = (char **)(sp2 + (auxv - sp));
|
||||
auxv = sp2 + (auxv - sp);
|
||||
sp = sp2;
|
||||
|
||||
/* allocate ephemeral memory for reading file */
|
||||
n = sizeof(union ElfEhdrBuf);
|
||||
ebuf = __builtin_alloca(n);
|
||||
ebuf = (union ElfEhdrBuf *)__builtin_alloca(n);
|
||||
for (; n > 0; n -= pagesz) {
|
||||
((char *)ebuf)[n - 1] = 0;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "ape/ape.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
#ifdef __aarch64__
|
||||
|
@ -64,7 +65,7 @@ ape.ident:
|
|||
.long 1
|
||||
1: .asciz "APE"
|
||||
2: .balign 4
|
||||
3: .long 107000000
|
||||
3: .long APE_VERSION_NOTE
|
||||
4: .size ape.ident,.-ape.ident
|
||||
.type ape.ident,@object
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue