2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 // TODO: Investigate this failure on x86_64 macOS back deployment
11 // XFAIL: use_system_cxx_lib && target=x86_64-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
13 // TODO: Figure out why this fails with Memory Sanitizer.
16 #include <libunwind.h>
21 void backtrace(int lower_bound
) {
22 unw_context_t context
;
23 unw_getcontext(&context
);
26 unw_init_local(&cursor
, &context
);
29 unw_word_t offset
= 0;
34 if (unw_get_proc_name(&cursor
, buffer
, sizeof(buffer
), &offset
) == 0) {
35 fprintf(stderr
, "Frame %d: %s+%p\n", n
, buffer
, (void*)offset
);
37 fprintf(stderr
, "Frame %d: Could not get name for cursor\n", n
);
42 } while (unw_step(&cursor
) > 0);
44 if (n
< lower_bound
) {
49 __attribute__((noinline
)) void test1(int i
) {
50 fprintf(stderr
, "starting %s\n", __func__
);
52 fprintf(stderr
, "finished %s\n", __func__
); // ensure return address is saved
55 __attribute__((noinline
)) void test2(int i
, int j
) {
56 fprintf(stderr
, "starting %s\n", __func__
);
59 fprintf(stderr
, "finished %s\n", __func__
); // ensure return address is saved
62 __attribute__((noinline
)) void test3(int i
, int j
, int k
) {
63 fprintf(stderr
, "starting %s\n", __func__
);
66 fprintf(stderr
, "finished %s\n", __func__
); // ensure return address is saved
70 unw_context_t context
;
71 unw_getcontext(&context
);
74 unw_init_local(&cursor
, &context
);
77 int ret
= unw_get_proc_info(&cursor
, &info
);
78 if (ret
!= UNW_ESUCCESS
)
81 // Set the IP to an address clearly outside any function.
82 unw_set_reg(&cursor
, UNW_REG_IP
, (unw_word_t
)0);
84 ret
= unw_get_proc_info(&cursor
, &info
);
85 if (ret
!= UNW_ENOINFO
)
89 void test_reg_names() {
90 unw_context_t context
;
91 unw_getcontext(&context
);
94 unw_init_local(&cursor
, &context
);
96 int max_reg_num
= -100;
99 #elif defined(__x86_64__)
103 const char prefix
[] = "unknown";
104 for (int i
= -2; i
< max_reg_num
; ++i
) {
105 if (strncmp(prefix
, unw_regname(&cursor
, i
), sizeof(prefix
) - 1) == 0)
109 if (strncmp(prefix
, unw_regname(&cursor
, max_reg_num
+ 1),
110 sizeof(prefix
) - 1) != 0)
114 #if defined(__x86_64__)
115 void test_reg_get_set() {
116 unw_context_t context
;
117 unw_getcontext(&context
);
120 unw_init_local(&cursor
, &context
);
122 for (int i
= 0; i
< 17; ++i
) {
123 const unw_word_t set_value
= 7;
124 if (unw_set_reg(&cursor
, i
, set_value
) != UNW_ESUCCESS
)
127 unw_word_t get_value
= 0;
128 if (unw_get_reg(&cursor
, i
, &get_value
) != UNW_ESUCCESS
)
131 if (set_value
!= get_value
)
136 void test_fpreg_get_set() {
137 unw_context_t context
;
138 unw_getcontext(&context
);
141 unw_init_local(&cursor
, &context
);
143 // get/set is not implemented for x86_64 fpregs.
144 for (int i
= 17; i
< 33; ++i
) {
145 const unw_fpreg_t set_value
= 7;
146 if (unw_set_fpreg(&cursor
, i
, set_value
) != UNW_EBADREG
)
149 unw_fpreg_t get_value
= 0;
150 if (unw_get_fpreg(&cursor
, i
, &get_value
) != UNW_EBADREG
)
155 void test_reg_get_set() {}
156 void test_fpreg_get_set() {}
159 int main(int, char**) {
166 test_fpreg_get_set();