Mercurial > hg > CbC > CbC_llvm
comparison libunwind/test/bad_unwind_info.pass.cpp @ 236:c4bab56944e8 llvm-original
LLVM 16
author | kono |
---|---|
date | Wed, 09 Nov 2022 17:45:10 +0900 |
parents | |
children | 1f2b6ac9f198 |
comparison
equal
deleted
inserted
replaced
232:70dce7da266c | 236:c4bab56944e8 |
---|---|
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 //===----------------------------------------------------------------------===// | |
9 | |
10 // Ensure that libunwind doesn't crash on invalid info; the Linux aarch64 | |
11 // sigreturn frame check would previously attempt to access invalid memory in | |
12 // this scenario. | |
13 // REQUIRES: linux && (target={{aarch64-.+}} || target={{s390x-.+}} || target={{x86_64-.+}}) | |
14 | |
15 // GCC doesn't support __attribute__((naked)) on AArch64. | |
16 // UNSUPPORTED: gcc | |
17 | |
18 // Inline assembly is incompatible with MSAN. | |
19 // UNSUPPORTED: msan | |
20 | |
21 #undef NDEBUG | |
22 #include <assert.h> | |
23 #include <libunwind.h> | |
24 #include <stdio.h> | |
25 | |
26 __attribute__((naked)) void bad_unwind_info() { | |
27 #if defined(__aarch64__) | |
28 __asm__("// not using 0 because unwinder was already resilient to that\n" | |
29 "mov x8, #4\n" | |
30 "stp x30, x8, [sp, #-16]!\n" | |
31 ".cfi_def_cfa_offset 16\n" | |
32 "// purposely use incorrect offset for x30\n" | |
33 ".cfi_offset x30, -8\n" | |
34 "bl stepper\n" | |
35 "ldr x30, [sp], #16\n" | |
36 ".cfi_def_cfa_offset 0\n" | |
37 ".cfi_restore x30\n" | |
38 "ret\n"); | |
39 #elif defined(__s390x__) | |
40 __asm__("stmg %r14,%r15,112(%r15)\n" | |
41 "mvghi 104(%r15),4\n" | |
42 "# purposely use incorrect offset for %r14\n" | |
43 ".cfi_offset 14, -56\n" | |
44 ".cfi_offset 15, -40\n" | |
45 "lay %r15,-160(%r15)\n" | |
46 ".cfi_def_cfa_offset 320\n" | |
47 "brasl %r14,stepper\n" | |
48 "lmg %r14,%r15,272(%r15)\n" | |
49 ".cfi_restore 15\n" | |
50 ".cfi_restore 14\n" | |
51 ".cfi_def_cfa_offset 160\n" | |
52 "br %r14\n"); | |
53 #elif defined(__x86_64__) | |
54 __asm__("pushq %rbx\n" | |
55 ".cfi_def_cfa_offset 16\n" | |
56 "movq 8(%rsp), %rbx\n" | |
57 "# purposely corrupt return value on stack\n" | |
58 "movq $4, 8(%rsp)\n" | |
59 "callq stepper\n" | |
60 "movq %rbx, 8(%rsp)\n" | |
61 "popq %rbx\n" | |
62 ".cfi_def_cfa_offset 8\n" | |
63 "ret\n"); | |
64 #else | |
65 #error This test is only supported on aarch64, s390x, or x86-64 | |
66 #endif | |
67 } | |
68 | |
69 extern "C" void stepper() { | |
70 unw_cursor_t cursor; | |
71 unw_context_t uc; | |
72 unw_getcontext(&uc); | |
73 unw_init_local(&cursor, &uc); | |
74 // stepping to bad_unwind_info should succeed | |
75 assert(unw_step(&cursor) > 0); | |
76 // stepping past bad_unwind_info should fail but not crash | |
77 assert(unw_step(&cursor) <= 0); | |
78 } | |
79 | |
80 int main() { bad_unwind_info(); } |