Loading...
tests/thread_stack_pcs.c Libc-1725.40.4 Libc-1506.40.4
--- Libc/Libc-1725.40.4/tests/thread_stack_pcs.c
+++ Libc/Libc-1506.40.4/tests/thread_stack_pcs.c
@@ -1,17 +1,8 @@
 #include <darwintest.h>
-#include <mach-o/dyld_priv.h>
 #include <thread_stack_pcs.h>
-#include <execinfo.h>
 #include <fake_swift_async.h>
 #include <pthread/private.h>
 #include <stdint.h>
-#include <stdlib.h>
-
-#if __arm64e__
-#define TARGET_CPU_ARM64E true
-#else
-#define TARGET_CPU_ARM64E false
-#endif
 
 static void *test_function_ret_addr;
 
@@ -52,8 +43,8 @@
         // 4 level1_func
         T_EXPECT_EQ(frames, 5, "Got the right number of async frames");
         T_EXPECT_EQ(callstack[2], __builtin_return_address(0), "Found fake_async_frame");
-        T_EXPECT_EQ(callstack[3], ptrauth_strip((void*)&level2_func, ptrauth_key_function_pointer) + 1, "Found level2_func");
-        T_EXPECT_EQ(callstack[4], ptrauth_strip((void*)&level1_func, ptrauth_key_function_pointer) + 1, "Found level1_func");
+        T_EXPECT_EQ(callstack[3], ptrauth_strip(&level2_func, ptrauth_key_function_pointer) + 1, "Found level2_func");
+        T_EXPECT_EQ(callstack[4], ptrauth_strip(&level1_func, ptrauth_key_function_pointer) + 1, "Found level1_func");
   } else {
         unsigned frames;
         int ret = thread_stack_pcs(callstack, 16, &frames);
@@ -112,527 +103,3 @@
     fake_async_frame(true);
 }
 
-//
-// split_stack_call_impl assembly implementation.
-//
-
-#if defined(__x86_64__)
-asm("\t.private_extern _split_stack_call_impl\n\t"
-    ".p2align    4, 0x90\n"
-"_split_stack_call_impl:\n\t"
-    "## new_stack -> %rdi\n\t"
-    "## new_stack_size -> %rsi\n\t"
-    "## func -> %rdx\n\t"
-    "## data -> %rcx\n\t"
-    ".cfi_startproc\n\t"
-    "pushq %rbp\n\t"
-    ".cfi_def_cfa_offset 16\n\t"
-    ".cfi_offset %rbp, -16\n\t"
-    "movq %rsp, %rbp\n\t"
-    ".cfi_def_cfa_register %rbp\n\t"
-    "# setup %rsp in the new stack space\n\t"
-    "leaq (%rdi, %rsi), %rsp\n\t"
-    "# move 'data' argument in %rdi\n\t"
-    "movq %rcx, %rdi\n\t"
-	"# move return address in %rsi\n\t"
-	"movq 0x8(%rbp), %rsi\n\t"
-    "# indirect jump to the function\n\t"
-    "callq *%rdx\n\t"
-    "# restore original %rsp\n\t"
-    "movq %rbp, %rsp\n\t"
-    "popq %rbp\n\t"
-    "retq\n\t"
-    ".cfi_endproc");
-#elif defined(__arm64__)
-#ifdef __arm64e__
-asm(".macro FN_PROLOG\n\t"
-    "pacibsp\n"
-".endmacro\n"
-".macro FN_EPILOG\n\t"
-    "retab\n"
-".endmacro\n"
-".macro RETADDR reg\n\t"
-	"mov \\reg, x30\n\t"
-	"xpaci \\reg\n"
-".endmacro\n"
-".macro INDCALL reg\n\t"
-    "blraaz \\reg\n"
-".endmacro");
-
-#else
-asm(".macro FN_PROLOG\n"
-".endmacro\n"
-".macro FN_EPILOG\n\t"
-    "ret\n"
-".endmacro\n"
-".macro RETADDR reg\n\t"
-	"mov \\reg, x30\n"
-".endmacro\n"
-".macro INDCALL reg\n\t"
-    "blr \\reg\n"
-".endmacro");
-#endif
-asm("\t.private_extern _split_stack_call_impl\n\t"
-	  ".p2align	2\n"
-"_split_stack_call_impl:\n\t"
-    "; new_stack -> x0\n\t"
-    "; new_stack_size -> x1\n\t"
-    "; func -> x2\n\t"
-    "; data -> x3\n\t"
-    ".cfi_startproc\n\t"
-    "FN_PROLOG\n\t"
-    "stp x29, x30, [sp, #-16]!\n\t"
-    "mov x29, sp\n\t"
-	".cfi_def_cfa w29, 16\n\t"
-	".cfi_offset w30, -8\n\t"
-	".cfi_offset w29, -16\n\t"
-    "; setup `sp` in the new stack space\n\t"
-    "add sp, x0, x1\n\t"
-    "; move 'data' argument in `x0`\n\t"
-    "mov x0, x3\n\t"
-	"; move our return address (in lr) into `x1`\n\t"
-	"RETADDR x1\n\t"
-    "; indirect call to the function\n\t"
-    "INDCALL x2\n\t"
-    "; restore original `sp`\n\t"
-    "mov sp, x29\n\t"
-    "ldp x29, x30, [sp], #16\n\t"
-    "FN_EPILOG\n\t"
-    ".cfi_endproc");
-#else
-#error "Unsupported architecture"
-#endif
-
-// Passes ctx to f in the first argument, and the return address of
-// _split_stack_call_impl in the second
-void split_stack_call_impl(void * stack, size_t stack_size, void (*f)(void*, void*), void *ctx);
-
-__attribute__((noinline)) __attribute__((not_tail_called))
-void non_default_stack_test_l2(void *ret2, void *ret3, void *ret4)
-{
-	void *ret1 = __builtin_return_address(0);
-
-	vm_address_t callstack[16];
-	unsigned frames;
-	thread_stack_pcs(callstack, 16, &frames);
-
-	// The 4 pcs we expect
-	// 0 thread_stack_pcs
-	// 1 non_default_stack_test_l2
-	// 2 non_default_stack_test (in ret1)
-	// 3 split_stack_call_impl (in ret2)
-	// 4 testmain (in ret3)
-	// 5 darwintest testrunner (in ret4)
-	// ...
-	T_EXPECT_GE(frames, 4, "Got the right number of stack frames");
-	T_EXPECT_EQ((void *)callstack[2], ret1, "Found non_default_stack_test_l2 frame");
-	T_EXPECT_EQ((void *)callstack[3], ret2, "Found non_default_stack_test frame");
-	T_EXPECT_EQ((void *)callstack[4], ret3, "Found split_stack_call_impl frame");
-	T_EXPECT_EQ((void *)callstack[5], ret4, "Found test main frame");
-}
-
-__attribute__((noinline))
-void non_default_stack_test(void *testmain_retaddr, void *stack_call_retaddr)
-{
-	void *our_retaddr = __builtin_return_address(0);
-	non_default_stack_test_l2(our_retaddr, stack_call_retaddr, testmain_retaddr);
-}
-
-T_DECL(thread_stack_pcs_alt_stack, "tests thread_stack_pcs when called from a non-default stack")
-{
-	const size_t stack_size = 32768;
-	void *stack = malloc(stack_size);
-	T_ASSERT_NOTNULL(stack, "Allocated non-default stack %p", stack);
-
-	void *ret_addr = __builtin_return_address(0);
-	split_stack_call_impl(stack, stack_size, non_default_stack_test, ret_addr);
-
-	free(stack);
-}
-
-// Sets some high bits in the stacked link register to corrupt the fp chain,
-// then calls into backtrace() to make sure we don't crash inside libc.
-void call_func_with_broken_fp_chain(void (*f)(void), void *ssi_retaddr);
-
-
-// On 64 bit systems, increment the stacked frame pointer by 16GB to make it
-// unlikely that it lands on a mapped address. On 32 bit systems, we need to
-// decrease this to 1GB to avoid overflowing to the same (legal) value
-#ifdef __LP64__
-#define FP_BREAK_OFFSET "0x400000000"
-#else
-#define FP_BREAK_OFFSET "0x40000000"
-#endif
-
-#if defined(__x86_64__)
-asm("\t.private_extern _call_func_with_broken_fp_chain\n\t"
-    ".p2align    4, 0x90\n"
-"_call_func_with_broken_fp_chain:\n\t"
-    "## ctx -> %rdi\n\t"
-    "## ssi_retaddr (unused) -> %rsi\n\t"
-    ".cfi_startproc\n\t"
-    "pushq %rbp\n\t"
-    ".cfi_def_cfa_offset 16\n\t"
-    ".cfi_offset %rbp, -16\n\t"
-    "movq %rsp, %rbp\n\t"
-	"# increment bp by 16GB to get callee to push a broken fp chain\n\t"
-	"movq $" FP_BREAK_OFFSET ", %rsi\n\t"
-	"addq %rsi, %rbp\n\t"
-    ".cfi_def_cfa_register %rbp\n\t"
-    "# indirect call to f\n\t"
-    "callq *%rdi\n\t"
-	"# decrement bp by 16GB before moving it to sp\n\t"
-	"movq $" FP_BREAK_OFFSET ", %rsi\n\t"
-	"subq %rsi, %rbp\n\t"
-    "# restore original %rsp\n\t"
-    "movq %rbp, %rsp\n\t"
-	"popq %rbp\n\t"
-    "retq\n\t"
-    ".cfi_endproc");
-#elif defined(__arm64__)
-asm("\t.private_extern _call_func_with_broken_fp_chain\n\t"
-	  ".p2align	2\n"
-"_call_func_with_broken_fp_chain:\n\t"
-    "; f -> x0\n\t"
-    "; ssi_retaddr (unused) -> x1\n\t"
-    ".cfi_startproc\n\t"
-    "FN_PROLOG\n\t"
-	"; store fp+16GB on the stack (clobbers unused arg1)\n\t"
-	"mov x1, #" FP_BREAK_OFFSET "\n\t"
-	"add x1, x29, x1\n\t"
-    "stp x1, x30, [sp, #-16]!\n\t"
-    "mov x29, sp\n\t"
-	".cfi_def_cfa w29, 16\n\t"
-	".cfi_offset w30, -8\n\t"
-	".cfi_offset w29, -16\n\t"
-    "; indirect call to f\n\t"
-    "INDCALL x0\n\t"
-    "; restore original `sp`\n\t"
-    "mov sp, x29\n\t"
-    "ldp x29, x30, [sp], #16\n\t"
-	"; Remove 16GB offset from fp on stack\n\t"
-	"mov x1, #" FP_BREAK_OFFSET "\n\t"
-    "sub x29, x29, x1\n\t"
-    "FN_EPILOG\n\t"
-    ".cfi_endproc");
-#else
-#error "Unsupported architecture"
-#endif
-
-static void call_backtrace_helper(void)
-{
-	// called on non-default stack with a broken fp chain.
-	void * backtrace_buffer[10];
-	int frames = backtrace(&backtrace_buffer[0], 10);
-	// Without the maximum frame size, we'd typically crash here. Assert that
-	// we didn't enumerate past the broken fp linkage, so that we're guaranteed
-	// to assert at least one thing in this test case and get a pass
-	T_ASSERT_LT(frames, 5, "Didn't enumerate too many frames\n", frames);
-}
-
-T_DECL(thread_stack_pcs_alt_broken_fp_chain,
-		"Check that backtrace() doesn't crash when fp chain is broken")
-{
-	const size_t stack_size = 32768;
-	void *stack = malloc(stack_size);
-	T_ASSERT_NOTNULL(stack, "Allocated non-default stack %p", stack);
-
-	split_stack_call_impl(stack, stack_size,
-			(void *)&call_func_with_broken_fp_chain, (void *)&call_backtrace_helper);
-
-	free(stack);
-}
-
-struct many_frames_args {
-	vm_address_t *buffer;
-	unsigned buffer_size;
-	unsigned recurse_depth;
-	unsigned ret_frames;
-	bool use_backtrace;
-};
-
-__attribute__((noinline))
-__attribute__((disable_tail_calls))
-void recursive_thread_stack_pcs(struct many_frames_args* args, void *unused)
-{
-	T_QUIET; T_ASSERT_NE(args->recurse_depth, 0, "Invalid recurse depth");
-	if (--args->recurse_depth) {
-		return recursive_thread_stack_pcs(args, NULL);
-	} else {
-		if (args->use_backtrace) {
-			args->ret_frames = backtrace(args->buffer, args->buffer_size);
-		} else {
-			thread_stack_pcs(args->buffer, args->buffer_size, &args->ret_frames);
-		}
-	}
-}
-
-T_DECL(thread_stack_pcs_alt_exact_frames,
-		"Enumerate a max of 16 frames with 16 frames in the non-default stack")
-{
-	const size_t stack_size = 32768;
-	void *stack = malloc(stack_size);
-	T_ASSERT_NOTNULL(stack, "Allocated non-default stack %p", stack);
-
-	// Oversize buffer to avoid breaking the stack and crashing
-	vm_address_t buffer[32] = { 0 };
-	struct many_frames_args arg = {
-		.buffer = &buffer,
-		.buffer_size = 16,
-		 // The top frame is thread_stack_pcs, so only recurse 15 times
-		.recurse_depth = 15,
-		.ret_frames = 0,
-		.use_backtrace = false,
-	};
-
-	split_stack_call_impl(stack, stack_size, recursive_thread_stack_pcs, &arg);
-
-	T_ASSERT_LE(arg.ret_frames, 16, "Too many frames walked");
-	T_ASSERT_EQ(buffer[16], 0, "Buffer not overwritten");
-
-	free(stack);
-}
-
-T_DECL(thread_stack_pcs_non_default_many_frames,
-		"Enumerate a max of 16 frames with more than that in non-default stack")
-{
-	const size_t stack_size = 32768;
-	void *stack = malloc(stack_size);
-	T_ASSERT_NOTNULL(stack, "Allocated non-default stack %p", stack);
-
-	vm_address_t buffer[32] = { 0 };
-	struct many_frames_args arg = {
-		.buffer = &buffer,
-		.buffer_size = 16,
-		.recurse_depth = 20,
-		.ret_frames = 0,
-		.use_backtrace = false,
-	};
-
-	split_stack_call_impl(stack, stack_size, recursive_thread_stack_pcs, &arg);
-
-	T_ASSERT_LE(arg.ret_frames, 16, "Too many frames walked");
-	T_ASSERT_EQ(buffer[16], 0, "Buffer not overwritten");
-
-	free(stack);
-}
-
-T_DECL(thread_stack_pcs_alt_stack_with_backtrace,
-		"Check that we can skip the top frame in non-default stack")
-{
-	const size_t stack_size = 32768;
-	void *stack = malloc(stack_size);
-	T_ASSERT_NOTNULL(stack, "Allocated non-default stack %p", stack);
-
-	vm_address_t buffer[16] = { 0 };
-	struct many_frames_args arg = {
-		.buffer = &buffer,
-		.buffer_size = 16,
-		.recurse_depth = 20,
-		.ret_frames = 0,
-		// backtrace() sets skip to 1 (to drop the backtrace() frame)
-		.use_backtrace = true,
-	};
-
-	split_stack_call_impl(stack, stack_size, recursive_thread_stack_pcs, &arg);
-
-	T_ASSERT_EQ(arg.ret_frames, 16, "Walked 16 frames");
-	// The top two frames should both be within recursive_thread_stack_pcs.
-	// They'll be slightly different from each other, but should both be within
-	// the same function. To check the latter, assume that they should be
-	// within 1k of each other
-	uintptr_t start =
-			(uintptr_t)ptrauth_strip((void*)&recursive_thread_stack_pcs,
-			ptrauth_key_function_pointer);
-	const vm_address_t max_allowed_difference = 1024;
-	T_ASSERT_GT((uintptr_t)buffer[0], start,
-		"Top frame is in recursive_thread_stack_pcs");
-	T_ASSERT_GT((uintptr_t)buffer[1], start,
-		"Second frame is in recursive_thread_stack_pcs");
-	T_ASSERT_NE((uintptr_t)buffer[0], (uintptr_t)buffer[1],
-		"Top frame and second frame differ (0x%lx, 0x%lx)", buffer[0], buffer[1]);
-	T_ASSERT_EQ((uintptr_t)buffer[1], (uintptr_t)buffer[2],
-		"Frames 2 and 3 are equal (recursive function)");
-	if (buffer[0] > buffer[1]) {
-		T_ASSERT_LE(buffer[0] - buffer[1], max_allowed_difference,
-			"Top two frames are close to each other");
-	} else {
-		T_ASSERT_LE(buffer[1] - buffer[0], max_allowed_difference,
-			"Top two frames are close to each other");
-	}
-
-	free(stack);
-}
-
-T_DECL(thread_stack_pcs_alt_stack_few_frames,
-		"Check that backtrace() works with fewer than max stack frames")
-{
-	const size_t stack_size = 32768;
-	void *stack = malloc(stack_size);
-	T_ASSERT_NOTNULL(stack, "Allocated non-default stack %p", stack);
-
-	vm_address_t buffer[16] = { 0 };
-	struct many_frames_args arg = {
-		.buffer = &buffer,
-		.buffer_size = 16,
-		.recurse_depth = 3,
-		.ret_frames = 0,
-		// backtrace() sets skip to 1 (to drop the backtrace() frame)
-		.use_backtrace = true,
-	};
-
-	split_stack_call_impl(stack, stack_size, recursive_thread_stack_pcs, &arg);
-
-	T_ASSERT_LT(arg.ret_frames, 16, "Walked fewer than 16 frames");
-	// The top two frames should both be within recursive_thread_stack_pcs.
-	// They'll be slightly different from each other, but should both be within
-	// the same function. To check the latter, assume that they should be
-	// within 1k of each other
-	uintptr_t start =
-			(uintptr_t)ptrauth_strip((void*)&recursive_thread_stack_pcs,
-			ptrauth_key_function_pointer);
-	const vm_address_t max_allowed_difference = 1024;
-	T_ASSERT_GT((uintptr_t)buffer[0], start,
-		"Top frame is in recursive_thread_stack_pcs");
-	T_ASSERT_GT((uintptr_t)buffer[1], start,
-		"Second frame is in recursive_thread_stack_pcs");
-	T_ASSERT_NE((uintptr_t)buffer[0], (uintptr_t)buffer[1],
-		"Top frame and second frame differ (0x%lx, 0x%lx)", buffer[0], buffer[1]);
-	T_ASSERT_EQ((uintptr_t)buffer[1], (uintptr_t)buffer[2],
-		"Frames 2 and 3 are equal (recursive function)");
-	if (buffer[0] > buffer[1]) {
-		T_ASSERT_LE(buffer[0] - buffer[1], max_allowed_difference,
-			"Top two frames are close to each other");
-	} else {
-		T_ASSERT_LE(buffer[1] - buffer[0], max_allowed_difference,
-			"Top two frames are close to each other");
-	}
-
-	free(stack);
-}
-
-#if defined(__arm64e__)
-
-struct dyld_stack_context
-{
-    // We might go dyld->regular->dyld->...
-    // These track the next stack location to push a new alternative/regular frame
-    void* nextAlternativeStackAddr;
-    void* nextRegularStackAddr;
-
-    // For the test methods to record their data in
-    void* thread_stack_pcs_dyld_stack_retaddr;
-    void* dyld_call_alternative_stack_retaddr;
-    void* dyld_call_regular_stack_retaddr;
-    void* dyld_call_alternative_stack_again_retaddr;
-    void* dyld_call_regular_stack_again_retaddr;
-};
-
-__attribute__((noinline))
-__attribute__((naked))
-__attribute__((not_tail_called))
-static void callAndSwapStack(void* nextStackPtr, void** prevStackPtr, void (*callback)(struct dyld_stack_context*), struct dyld_stack_context* context)
-{
-    asm volatile("pacibsp\n"
-                 "mov       x16, sp\n"
-                 "ldr       x8,  [x1]\n"                // load the old value in prevStackPtr
-                 "str       x16, [x1]\n"                // save next stack value to prevStackPtr
-                 "mov       x17, x0\n"
-                 "pacdb     x16, x17\n"                 // sign the old sp
-                 "sub       x17, x17, #0x30\n"          // subtract space from stack
-                 "stp       x1, x8,   [x17, #0x00]\n"   // save prevStackPtr and its old target value
-                 "stp       xzr, x16, [x17, #0x10]\n"   // save old sp
-                 "stp       x29, x30, [x17, #0x20]\n"   // save fp, lr
-                 "mov       sp, x17\n"                  // switch to new stack
-                 "add       x29, x17, #0x20\n"          // switch to new frame
-                 "mov       x0, x3\n"                   // move context in to the first argument
-                 "blraaz    x2\n"                       // call the function
-                 "ldp       x1, x8,   [sp, #0x00]\n"    // load prevStackPtr and its current value when we started this function
-                 "ldp       x29, x30, [sp, #0x20]\n"    // restore fp, lr
-                 "ldp       xzr, x16, [sp, #0x10]\n"    // load old sp
-                 "add       sp, sp, #0x30\n"            // move the stack back up before the auth
-                 "autdb     x16, sp\n"                  // auth old sp
-                 "mov       sp, x16\n"                  // restore old sp
-                 "str       x8, [x1]\n"                 // restore the old value in prevStackPtr
-                 "retab\n");
-}
-
-__attribute__((noinline)) __attribute__((not_tail_called))
-static void thread_stack_pcs_dyld_stack_test(struct dyld_stack_context* context)
-{
-    void *ret1 = __builtin_return_address(0);
-
-    vm_address_t* callstack[16];
-    unsigned frames;
-    thread_stack_pcs(callstack, 16, &frames);
-
-    // The pcs we expect
-    // 0  thread_stack_pcs
-    // 1  thread_stack_pcs_dyld_stack_test
-    // 2  callAndSwapStack
-    // 3  dyld_call_regular_stack_again
-    // 4  callAndSwapStack
-    // 5  dyld_call_alternative_stack_again
-    // 6  callAndSwapStack
-    // 7  dyld_call_regular_stack
-    // 8  callAndSwapStack
-    // 9  dyld_call_alternative_stack
-    // 10 testmain
-    // 11 darwintest testrunner
-    // ...
-    T_EXPECT_GE(frames, 10, "Got the right number of stack frames");
-    T_EXPECT_EQ(callstack[4], context->dyld_call_regular_stack_again_retaddr, "Found dyld_call_regular_stack_again frame");
-    T_EXPECT_EQ(callstack[6], context->dyld_call_alternative_stack_again_retaddr, "Found dyld_call_alternative_stack_again frame");
-    T_EXPECT_EQ(callstack[8], context->dyld_call_regular_stack_again_retaddr, "Found dyld_call_regular_stack frame");
-    T_EXPECT_EQ(callstack[10], context->dyld_call_alternative_stack_retaddr, "Found dyld_call_alternative_stack frame");
-}
-
-__attribute__((noinline)) __attribute__((not_tail_called))
-static void dyld_call_regular_stack_again(struct dyld_stack_context* context)
-{
-    context->dyld_call_regular_stack_again_retaddr = __builtin_return_address(0);
-    callAndSwapStack(context->nextRegularStackAddr, &context->nextAlternativeStackAddr, &thread_stack_pcs_dyld_stack_test, context);
-}
-
-__attribute__((noinline)) __attribute__((not_tail_called))
-static void dyld_call_alternative_stack_again(struct dyld_stack_context* context)
-{
-    context->dyld_call_alternative_stack_again_retaddr = __builtin_return_address(0);
-    callAndSwapStack(context->nextAlternativeStackAddr, &context->nextRegularStackAddr, &dyld_call_regular_stack_again, context);
-}
-
-__attribute__((noinline)) __attribute__((not_tail_called))
-static void dyld_call_regular_stack(struct dyld_stack_context* context)
-{
-    context->dyld_call_regular_stack_retaddr = __builtin_return_address(0);
-    callAndSwapStack(context->nextRegularStackAddr, &context->nextAlternativeStackAddr, &dyld_call_alternative_stack_again, context);
-}
-
-__attribute__((noinline)) __attribute__((not_tail_called))
-static void dyld_call_alternative_stack(struct dyld_stack_context* context)
-{
-    context->dyld_call_alternative_stack_retaddr = __builtin_return_address(0);
-    callAndSwapStack(context->nextAlternativeStackAddr, &context->nextRegularStackAddr, &dyld_call_regular_stack, context);
-}
-
-T_DECL(thread_stack_pcs_dyld_stack, "tests thread_stack_pcs when called from the dyld stack",
-       T_META_ENVVAR("DYLD_INSERT_LIBRARIES=@executable_path/thread_stack_pcs_helper"),
-       T_META_ENABLED(TARGET_CPU_ARM64E && !TARGET_OS_OSX))
-{
-    struct dyld_stack_context context;
-    const void *dyldstacktop = NULL;
-    const void *dyldstackbot = NULL;
-
-    _dyld_stack_range(&dyldstackbot, &dyldstacktop);
-
-    context.nextAlternativeStackAddr = dyldstacktop;
-    context.nextRegularStackAddr = NULL;
-    context.thread_stack_pcs_dyld_stack_retaddr = __builtin_return_address(0);
-    context.dyld_call_alternative_stack_retaddr = NULL;
-    context.dyld_call_regular_stack_retaddr = NULL;
-    context.dyld_call_alternative_stack_again_retaddr = NULL;
-    context.dyld_call_regular_stack_again_retaddr = NULL;
-
-    dyld_call_alternative_stack(&context);
-}
-#endif // defined(__arm64e__)