Polyfill auxiliary values on XNU

This commit is contained in:
Justine Tunney 2021-02-03 20:37:52 -08:00
parent a37960a3af
commit d934f38c99
6 changed files with 27 additions and 32 deletions

View file

@ -36,26 +36,10 @@ unsigned long getauxval(unsigned long at) {
if (at != -1) { if (at != -1) {
if (!IsWindows()) { if (!IsWindows()) {
if (!g_auxv) return 0; if (!g_auxv) return 0;
if (IsXnu()) { for (const unsigned long *ap = g_auxv; *ap; ap += 2) {
if (at) { if (ap[0] == at) {
const char *name = res = ap[1];
at == AT_EXECFN ? "executable_path" : (const char *)at; break;
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;
}
} }
} }
} else { } else {

View file

@ -52,11 +52,23 @@ _start: test %rdi,%rdi
mov %rdx,%rdi mov %rdx,%rdi
repnz scasq repnz scasq
mov %rdi,%rcx # auxv 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 call cosmo
9: ud2 9: ud2
.endfn _start,weak,hidden .endfn _start,weak,hidden
#if SupportsXnu()
/ Macintosh userspace program entrypoint. / Macintosh userspace program entrypoint.
/ /
/ @param rsp is [n,argv₀..argvₙ₋₁,0,envp₀..,0,auxv₀..,0,..] / @param rsp is [n,argv₀..argvₙ₋₁,0,envp₀..,0,auxv₀..,0,..]
@ -65,3 +77,4 @@ _start: test %rdi,%rdi
_xnu: movb $XNU,__hostos(%rip) _xnu: movb $XNU,__hostos(%rip)
jmp 0b jmp 0b
.endfn _xnu,weak,hidden .endfn _xnu,weak,hidden
#endif

View file

@ -77,12 +77,11 @@ STATIC_YOINK("_init_asan");
} \ } \
} while (0) } while (0)
#define REQUIRE(FUNC) \ #define REQUIRE(FUNC) \
do { \ do { \
if (!weaken(FUNC)) { \ if (!weaken(FUNC)) { \
__asan_write_string("asan needs " #FUNC "\n"); \ __asan_die("error: asan needs " #FUNC "\n"); \
__asan_exit(100); \ } \
} \
} while (0) } while (0)
struct AsanSourceLocation { struct AsanSourceLocation {
@ -448,7 +447,6 @@ static ssize_t __asan_write_string(const char *s) {
static wontreturn void __asan_abort(void) { static wontreturn void __asan_abort(void) {
if (weaken(__die)) weaken(__die)(); if (weaken(__die)) weaken(__die)();
if (weaken(abort)) weaken(abort)();
__asan_exit(134); __asan_exit(134);
} }
@ -753,7 +751,7 @@ void __asan_map_shadow(uintptr_t p, size_t n) {
weaken(TrackMemoryInterval)( weaken(TrackMemoryInterval)(
m, a, a, sm.maphandle, PROT_READ | PROT_WRITE, m, a, a, sm.maphandle, PROT_READ | PROT_WRITE,
MAP_PRIVATE | *weaken(MAP_ANONYMOUS) | MAP_FIXED) == -1) { 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); __asan_repstosb((void *)((uintptr_t)a << 16), kAsanUnmapped, 1 << 16);
} }

View file

@ -67,7 +67,7 @@ static noasan textwindows void MakeLongDoubleLongAgain(void) {
static noasan textwindows void NormalizeCmdExe(void) { static noasan textwindows void NormalizeCmdExe(void) {
uint32_t mode; uint32_t mode;
int64_t handle, hstdin, hstdout, hstderr; int64_t handle, hstdin, hstdout, hstderr;
if ((int)weakaddr("sys_v_ntsubsystem") == kNtImageSubsystemWindowsCui && if ((int)weakaddr("v_ntsubsystem") == kNtImageSubsystemWindowsCui &&
NtGetVersion() >= kNtVersionWindows10) { NtGetVersion() >= kNtVersionWindows10) {
hstdin = GetStdHandle(pushpop(kNtStdInputHandle)); hstdin = GetStdHandle(pushpop(kNtStdInputHandle));
hstdout = GetStdHandle(pushpop(kNtStdOutputHandle)); hstdout = GetStdHandle(pushpop(kNtStdOutputHandle));

View file

@ -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_SECURE 23 0 0 0 0
syscon auxv AT_BASE_PLATFORM 24 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_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_SYSINFO_EHDR 33 0 0 0 0
syscon auxv AT_NO_AUTOMOUNT 0x0800 0 0 0 0 syscon auxv AT_NO_AUTOMOUNT 0x0800 0 0 0 0

View file

@ -1,2 +1,2 @@
.include "libc/sysv/consts/syscon.inc" .include "libc/sysv/consts/syscon.inc"
.syscon auxv AT_EXECFN 31 999 999 999 999 .syscon auxv AT_EXECFN 31 31 999 999 999