]> git.saurik.com Git - apple/libpthread.git/blame - tests/stack.c
libpthread-416.100.3.tar.gz
[apple/libpthread.git] / tests / stack.c
CommitLineData
214d78a2
A
1#include <signal.h>
2#include <pthread/stack_np.h>
3
4#include "darwintest_defaults.h"
5#include <darwintest_utils.h>
6
7#if defined(__arm64__)
8#define call_chkstk(value) \
9 __asm__ volatile("orr x9, xzr, %0\t\n" \
10 "bl _thread_chkstk_darwin" : : "i"(value) : "x9")
214d78a2
A
11#elif defined(__x86_64__)
12#define call_chkstk(value) \
13 __asm__ volatile("movq %0, %%rax\t\n" \
14 "callq _thread_chkstk_darwin" : : "i"(value) : "rax")
214d78a2
A
15#elif defined(__i386__)
16#define call_chkstk(value) \
17 __asm__ volatile("movl %0, %%eax\t\n" \
18 "calll _thread_chkstk_darwin" : : "i"(value) : "eax")
214d78a2
A
19#endif
20
21static void
22got_signal(int signo __unused)
23{
24 T_PASS("calling with 1 << 24 crashed");
25 T_END;
26}
27
28T_DECL(chkstk, "chkstk",
29 T_META_ALL_VALID_ARCHS(YES), T_META_CHECK_LEAKS(NO))
30{
31#if defined(__arm__)
32 T_SKIP("not on armv7");
33#else
34
35 call_chkstk(1 << 8);
36 T_PASS("calling with 1 << 8");
37
38 call_chkstk(1 << 16);
39 T_PASS("calling with 1 << 16");
40
c6e5f90c
A
41 stack_t ss = {
42 .ss_sp = malloc(MINSIGSTKSZ),
43 .ss_size = MINSIGSTKSZ,
44 };
45 T_ASSERT_POSIX_SUCCESS(sigaltstack(&ss, NULL), "sigaltstack");
46
47 struct sigaction sa = {
48 .sa_handler = got_signal,
49 .sa_flags = SA_ONSTACK,
50 };
51 T_ASSERT_POSIX_SUCCESS(sigaction(SIGSEGV, &sa, NULL), "sigaction");
214d78a2 52
45deb508
A
53#if __LP64__
54 call_chkstk(1ul << 32);
55#else
56 call_chkstk(1ul << 24);
57#endif
214d78a2
A
58 T_FAIL("should have crashed");
59#endif
60}
61
62struct frame {
63 uintptr_t frame;
64 uintptr_t ret;
65};
66
67OS_NOINLINE OS_NOT_TAIL_CALLED
68static void
69do_stack_frame_decode_test(struct frame frames[], size_t n, size_t count)
70{
71 if (n < count) {
72 frames[n].frame = (uintptr_t)__builtin_frame_address(1);
73 frames[n].ret = (uintptr_t)__builtin_return_address(0);
74 do_stack_frame_decode_test(frames, n + 1, count);
75 } else {
76 uintptr_t frame = (uintptr_t)__builtin_frame_address(1);
77 uintptr_t ret;
78 while (count-- > 0) {
79 frame = pthread_stack_frame_decode_np(frame, &ret);
80 T_EXPECT_EQ(frames[count].frame, frame, "Frame %zd", count);
81 T_EXPECT_EQ(frames[count].ret, ret, "Retaddr %zd", count);
82 }
83 }
84}
85
86T_DECL(pthread_stack_frame_decode_np, "pthread_stack_frame_decode_np",
87 T_META_ALL_VALID_ARCHS(YES), T_META_CHECK_LEAKS(NO))
88{
89 struct frame frames[10];
90 frames[0].frame = (uintptr_t)__builtin_frame_address(1);
91 frames[0].ret = (uintptr_t)__builtin_return_address(0);
92 do_stack_frame_decode_test(frames, 1, 10);
93}