[LLD][COFF] Add support for /noimplib
[llvm-project.git] / libunwind / test / libunwind_01.pass.cpp
blob8b4825ac30dca86ef80386f14e4bfb54040726e5
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
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
7 //
8 //===----------------------------------------------------------------------===//
10 // TODO: Investigate these failures on x86_64 macOS back deployment
11 // UNSUPPORTED: target=x86_64-apple-darwin{{.+}}
13 // TODO: Figure out why this fails with Memory Sanitizer.
14 // XFAIL: msan
16 #include <libunwind.h>
17 #include <stdlib.h>
18 #include <string.h>
20 void backtrace(int lower_bound) {
21 unw_context_t context;
22 unw_getcontext(&context);
24 unw_cursor_t cursor;
25 unw_init_local(&cursor, &context);
27 int n = 0;
28 do {
29 ++n;
30 if (n > 100) {
31 abort();
33 } while (unw_step(&cursor) > 0);
35 if (n < lower_bound) {
36 abort();
40 void test1(int i) {
41 backtrace(i);
44 void test2(int i, int j) {
45 backtrace(i);
46 test1(j);
49 void test3(int i, int j, int k) {
50 backtrace(i);
51 test2(j, k);
54 void test_no_info() {
55 unw_context_t context;
56 unw_getcontext(&context);
58 unw_cursor_t cursor;
59 unw_init_local(&cursor, &context);
61 unw_proc_info_t info;
62 int ret = unw_get_proc_info(&cursor, &info);
63 if (ret != UNW_ESUCCESS)
64 abort();
66 // Set the IP to an address clearly outside any function.
67 unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)0);
69 ret = unw_get_proc_info(&cursor, &info);
70 if (ret != UNW_ENOINFO)
71 abort();
74 void test_reg_names() {
75 unw_context_t context;
76 unw_getcontext(&context);
78 unw_cursor_t cursor;
79 unw_init_local(&cursor, &context);
81 int max_reg_num = -100;
82 #if defined(__i386__)
83 max_reg_num = 7;
84 #elif defined(__x86_64__)
85 max_reg_num = 32;
86 #endif
88 const char prefix[] = "unknown";
89 for (int i = -2; i < max_reg_num; ++i) {
90 if (strncmp(prefix, unw_regname(&cursor, i), sizeof(prefix) - 1) == 0)
91 abort();
94 if (strncmp(prefix, unw_regname(&cursor, max_reg_num + 1),
95 sizeof(prefix) - 1) != 0)
96 abort();
99 #if defined(__x86_64__)
100 void test_reg_get_set() {
101 unw_context_t context;
102 unw_getcontext(&context);
104 unw_cursor_t cursor;
105 unw_init_local(&cursor, &context);
107 for (int i = 0; i < 17; ++i) {
108 const unw_word_t set_value = 7;
109 if (unw_set_reg(&cursor, i, set_value) != UNW_ESUCCESS)
110 abort();
112 unw_word_t get_value = 0;
113 if (unw_get_reg(&cursor, i, &get_value) != UNW_ESUCCESS)
114 abort();
116 if (set_value != get_value)
117 abort();
121 void test_fpreg_get_set() {
122 unw_context_t context;
123 unw_getcontext(&context);
125 unw_cursor_t cursor;
126 unw_init_local(&cursor, &context);
128 // get/set is not implemented for x86_64 fpregs.
129 for (int i = 17; i < 33; ++i) {
130 const unw_fpreg_t set_value = 7;
131 if (unw_set_fpreg(&cursor, i, set_value) != UNW_EBADREG)
132 abort();
134 unw_fpreg_t get_value = 0;
135 if (unw_get_fpreg(&cursor, i, &get_value) != UNW_EBADREG)
136 abort();
139 #else
140 void test_reg_get_set() {}
141 void test_fpreg_get_set() {}
142 #endif
144 int main(int, char**) {
145 test1(1);
146 test2(1, 2);
147 test3(1, 2, 3);
148 test_no_info();
149 test_reg_names();
150 test_reg_get_set();
151 test_fpreg_get_set();
152 return 0;