]> git.saurik.com Git - apple/libpthread.git/blob - tests/stack.c
libpthread-330.201.1.tar.gz
[apple/libpthread.git] / tests / stack.c
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")
11 #define TRAPSIG SIGTRAP
12 #elif defined(__x86_64__)
13 #define call_chkstk(value) \
14 __asm__ volatile("movq %0, %%rax\t\n" \
15 "callq _thread_chkstk_darwin" : : "i"(value) : "rax")
16 #define TRAPSIG SIGILL
17 #elif defined(__i386__)
18 #define call_chkstk(value) \
19 __asm__ volatile("movl %0, %%eax\t\n" \
20 "calll _thread_chkstk_darwin" : : "i"(value) : "eax")
21 #define TRAPSIG SIGILL
22 #endif
23
24 static void
25 got_signal(int signo __unused)
26 {
27 T_PASS("calling with 1 << 24 crashed");
28 T_END;
29 }
30
31 T_DECL(chkstk, "chkstk",
32 T_META_ALL_VALID_ARCHS(YES), T_META_CHECK_LEAKS(NO))
33 {
34 #if defined(__arm__)
35 T_SKIP("not on armv7");
36 #else
37
38 call_chkstk(1 << 8);
39 T_PASS("calling with 1 << 8");
40
41 call_chkstk(1 << 16);
42 T_PASS("calling with 1 << 16");
43
44 signal(TRAPSIG, got_signal);
45
46 call_chkstk(1 << 24);
47 T_FAIL("should have crashed");
48 #endif
49 }
50
51 struct frame {
52 uintptr_t frame;
53 uintptr_t ret;
54 };
55
56 OS_NOINLINE OS_NOT_TAIL_CALLED
57 static void
58 do_stack_frame_decode_test(struct frame frames[], size_t n, size_t count)
59 {
60 if (n < count) {
61 frames[n].frame = (uintptr_t)__builtin_frame_address(1);
62 frames[n].ret = (uintptr_t)__builtin_return_address(0);
63 do_stack_frame_decode_test(frames, n + 1, count);
64 } else {
65 uintptr_t frame = (uintptr_t)__builtin_frame_address(1);
66 uintptr_t ret;
67 while (count-- > 0) {
68 frame = pthread_stack_frame_decode_np(frame, &ret);
69 T_EXPECT_EQ(frames[count].frame, frame, "Frame %zd", count);
70 T_EXPECT_EQ(frames[count].ret, ret, "Retaddr %zd", count);
71 }
72 }
73 }
74
75 T_DECL(pthread_stack_frame_decode_np, "pthread_stack_frame_decode_np",
76 T_META_ALL_VALID_ARCHS(YES), T_META_CHECK_LEAKS(NO))
77 {
78 struct frame frames[10];
79 frames[0].frame = (uintptr_t)__builtin_frame_address(1);
80 frames[0].ret = (uintptr_t)__builtin_return_address(0);
81 do_stack_frame_decode_test(frames, 1, 10);
82 }