Skip to content

Commit

Permalink
Polyfill auxiliary values on XNU
Browse files Browse the repository at this point in the history
  • Loading branch information
jart committed Feb 4, 2021
1 parent a37960a commit d934f38
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 32 deletions.
24 changes: 4 additions & 20 deletions libc/calls/getauxval.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,10 @@ unsigned long getauxval(unsigned long at) {
if (at != -1) {
if (!IsWindows()) {
if (!g_auxv) return 0;
if (IsXnu()) {
if (at) {
const char *name =
at == AT_EXECFN ? "executable_path" : (const char *)at;
const char **auxv = (const char **)g_auxv;
unsigned namelen = strlen(name);
for (int i = 0; auxv[i]; ++i) {
if (strncmp(auxv[i], name, namelen) == 0 &&
auxv[i][namelen] == '=') {
res = (intptr_t)&auxv[i][namelen + 1];
break;
}
}
}
} else {
for (const unsigned long *ap = g_auxv; *ap; ap += 2) {
if (ap[0] == at) {
res = ap[1];
break;
}
for (const unsigned long *ap = g_auxv; *ap; ap += 2) {
if (ap[0] == at) {
res = ap[1];
break;
}
}
} else {
Expand Down
15 changes: 14 additions & 1 deletion libc/crt/crt.S
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,23 @@ _start: test %rdi,%rdi
mov %rdx,%rdi
repnz scasq
mov %rdi,%rcx # auxv
mov %ebx,%edi
#if SupportsXnu()
testb IsXnu()
jz 1f # polyfill xnu auxv
push $0 # auxv[1][1]=0
push $0 # auxv[1][0]=0
mov (%rcx),%rax # executable_path=BIN
lea 16(%rax),%rax # BIN
push %rax # auxv[0][0]=BIN
push $31 # auxv[0][0]=AT_EXECFN
mov %rsp,%rcx # auxv
#endif
1: mov %ebx,%edi
call cosmo
9: ud2
.endfn _start,weak,hidden

#if SupportsXnu()
/ Macintosh userspace program entrypoint.
/
/ @param rsp is [n,argv₀..argvₙ₋₁,0,envp₀..,0,auxv₀..,0,..]
Expand All @@ -65,3 +77,4 @@ _start: test %rdi,%rdi
_xnu: movb $XNU,__hostos(%rip)
jmp 0b
.endfn _xnu,weak,hidden
#endif
14 changes: 6 additions & 8 deletions libc/intrin/asan.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,11 @@ STATIC_YOINK("_init_asan");
} \
} while (0)

#define REQUIRE(FUNC) \
do { \
if (!weaken(FUNC)) { \
__asan_write_string("asan needs " #FUNC "\n"); \
__asan_exit(100); \
} \
#define REQUIRE(FUNC) \
do { \
if (!weaken(FUNC)) { \
__asan_die("error: asan needs " #FUNC "\n"); \
} \
} while (0)

struct AsanSourceLocation {
Expand Down Expand Up @@ -448,7 +447,6 @@ static ssize_t __asan_write_string(const char *s) {

static wontreturn void __asan_abort(void) {
if (weaken(__die)) weaken(__die)();
if (weaken(abort)) weaken(abort)();
__asan_exit(134);
}

Expand Down Expand Up @@ -753,7 +751,7 @@ void __asan_map_shadow(uintptr_t p, size_t n) {
weaken(TrackMemoryInterval)(
m, a, a, sm.maphandle, PROT_READ | PROT_WRITE,
MAP_PRIVATE | *weaken(MAP_ANONYMOUS) | MAP_FIXED) == -1) {
__asan_abort();
__asan_die("error: could not map asan shadow memory\n");
}
__asan_repstosb((void *)((uintptr_t)a << 16), kAsanUnmapped, 1 << 16);
}
Expand Down
2 changes: 1 addition & 1 deletion libc/runtime/winmain.greg.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ static noasan textwindows void MakeLongDoubleLongAgain(void) {
static noasan textwindows void NormalizeCmdExe(void) {
uint32_t mode;
int64_t handle, hstdin, hstdout, hstderr;
if ((int)weakaddr("sys_v_ntsubsystem") == kNtImageSubsystemWindowsCui &&
if ((int)weakaddr("v_ntsubsystem") == kNtImageSubsystemWindowsCui &&
NtGetVersion() >= kNtVersionWindows10) {
hstdin = GetStdHandle(pushpop(kNtStdInputHandle));
hstdout = GetStdHandle(pushpop(kNtStdOutputHandle));
Expand Down
2 changes: 1 addition & 1 deletion libc/sysv/consts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ syscon auxv AT_UCACHEBSIZE 21 0 0 0 0
syscon auxv AT_SECURE 23 0 0 0 0
syscon auxv AT_BASE_PLATFORM 24 0 0 0 0
syscon auxv AT_RANDOM 25 0 0 0 0 # address of sixteen bytes of random data
syscon auxv AT_EXECFN 31 999 999 999 999 # address of string containing first argument passed to execve() used when running program [faked on non-linux]
syscon auxv AT_EXECFN 31 31 999 999 999 # address of string containing first argument passed to execve() used when running program [faked on non-linux]
syscon auxv AT_SYSINFO_EHDR 33 0 0 0 0
syscon auxv AT_NO_AUTOMOUNT 0x0800 0 0 0 0

Expand Down
2 changes: 1 addition & 1 deletion libc/sysv/consts/AT_EXECFN.s
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
.include "libc/sysv/consts/syscon.inc"
.syscon auxv AT_EXECFN 31 999 999 999 999
.syscon auxv AT_EXECFN 31 31 999 999 999

0 comments on commit d934f38

Please sign in to comment.