Skip to content

Commit 1c2e7c1

Browse files
committed
Introduce SIP_DISABLED compile option for ape-m1.c
Systems that don't use SIP can now build APE Loader with this flag to get a performance speedup.
1 parent 0283f27 commit 1c2e7c1

File tree

2 files changed

+35
-18
lines changed

2 files changed

+35
-18
lines changed

ape/ape-m1.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,6 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
629629

630630
/* load from file */
631631
if (p[i].p_filesz) {
632-
long map1, map2;
633632
int prot1, prot2;
634633
unsigned long wipe;
635634
prot1 = prot;
@@ -653,22 +652,33 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
653652
addr = (void *)(dynbase + (p[i].p_vaddr & -pagesz));
654653
size = (p[i].p_vaddr & (pagesz - 1)) + p[i].p_filesz;
655654
if (prot1 & PROT_EXEC) {
655+
#ifdef SIP_DISABLED
656656
// if sip is disabled then we can load the executable segments
657-
// of the binary into memory without needing to copy anything!
657+
// off the binary into memory without needing to copy anything
658+
// which provides considerably better performance for building
658659
rc = sys_mmap(addr, size, prot1, flags, fd, p[i].p_offset & -pagesz);
659660
if (rc < 0) {
660-
if (rc != -EPERM) Pexit(exe, rc, "mmap(exec)");
661-
// apple arm64 won't allow PROT_EXEC mapping any unsigned file
662-
// however we are allowed to copy it into an anonymous mapping
663-
map1 = sys_mmap(0, size, PROT_READ, MAP_PRIVATE, fd,
664-
p[i].p_offset & -pagesz);
665-
if (map1 < 0) Pexit(exe, map1, "mmap(exec) workaround input");
666-
map2 = sys_mmap(addr, size, (prot1 = PROT_READ | PROT_WRITE),
667-
MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
668-
if (map2 < 0) Pexit(exe, map2, "mmap(exec) workaround output");
669-
memcpy((void *)map2, (void *)map1, size);
670-
munmap((void *)map1, size);
661+
if (rc == -EPERM) {
662+
Pexit(exe, rc,
663+
"map(exec) failed because SIP (System Integrity Protection) "
664+
"is enabled, but APE Loader was compiled with SIP_DISABLED");
665+
} else {
666+
Pexit(exe, rc, "map(exec) failed");
667+
}
671668
}
669+
#else
670+
// the issue is that if sip is enabled then, attempting to map
671+
// it with exec permission will cause xnu to phone home a hash
672+
// of the entire file to apple intelligence as a one time cost
673+
// which is literally minutes for executables holding big data
674+
// since there's no public apple api for detecting sip we read
675+
// as the default strategy which is slow but it works for both
676+
rc = sys_mmap(addr, size, (prot1 = PROT_READ | PROT_WRITE),
677+
MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
678+
if (rc < 0) Pexit(exe, rc, "prog mmap anon");
679+
rc = pread(fd, addr, p[i].p_filesz, p[i].p_offset & -pagesz);
680+
if (rc != p[i].p_filesz) Pexit(exe, -errno, "prog pread");
681+
#endif
672682
} else {
673683
rc = sys_mmap(addr, size, prot1, flags, fd, p[i].p_offset & -pagesz);
674684
if (rc < 0) Pexit(exe, rc, "prog mmap");

libc/log/libfatal.internal.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@ __funline void *__repstosb(void *di, char al, size_t cx) {
3232
: "0"(di), "1"(cx), "a"(al));
3333
return di;
3434
#else
35-
volatile char *volatile d = di;
36-
while (cx--) *d++ = al;
35+
char *d = di;
36+
while (cx--) {
37+
*d++ = al;
38+
asm volatile("" ::: "memory");
39+
}
3740
return (void *)d;
3841
#endif
3942
}
@@ -45,9 +48,12 @@ __funline void *__repmovsb(void *di, const void *si, size_t cx) {
4548
: "0"(di), "1"(si), "2"(cx), "m"(*(char(*)[cx])si));
4649
return di;
4750
#else
48-
volatile char *volatile d = di;
49-
volatile const char *volatile s = si;
50-
while (cx--) *d++ = *s++;
51+
char *d = di;
52+
const char *s = si;
53+
while (cx--) {
54+
*d++ = *s++;
55+
asm volatile("" ::: "memory");
56+
}
5157
return (void *)d;
5258
#endif
5359
}
@@ -56,6 +62,7 @@ __funline void *__mempcpy(void *d, const void *s, size_t n) {
5662
size_t i;
5763
for (i = 0; i < n; ++i) {
5864
((char *)d)[i] = ((const char *)s)[i];
65+
asm volatile("" ::: "memory");
5966
}
6067
return (char *)d + n;
6168
}

0 commit comments

Comments
 (0)