]>
Commit | Line | Data |
---|---|---|
04277e02 | 1 | /* Copyright (C) 1997-2019 Free Software Foundation, Inc. |
554066b8 MS |
2 | |
3 | This file is part of the GNU C Library. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public License as | |
7 | published by the Free Software Foundation; either version 2.1 of the | |
8 | License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library. If not, see | |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
554066b8 MS |
18 | |
19 | #include <sysdep.h> | |
20 | #include <jmpbuf-offsets.h> | |
140cc7ab | 21 | #include <stap-probe.h> |
554066b8 MS |
22 | |
23 | /* __longjmp(jmpbuf, val) */ | |
24 | ||
25 | ENTRY (__longjmp) | |
26 | cfi_def_cfa(x0, 0) | |
27 | cfi_offset(x19, JB_X19<<3) | |
28 | cfi_offset(x20, JB_X20<<3) | |
29 | cfi_offset(x21, JB_X21<<3) | |
30 | cfi_offset(x22, JB_X22<<3) | |
31 | cfi_offset(x23, JB_X23<<3) | |
32 | cfi_offset(x24, JB_X24<<3) | |
33 | cfi_offset(x25, JB_X25<<3) | |
34 | cfi_offset(x26, JB_X26<<3) | |
35 | cfi_offset(x27, JB_X27<<3) | |
36 | cfi_offset(x28, JB_X28<<3) | |
37 | cfi_offset(x29, JB_X29<<3) | |
38 | cfi_offset(x30, JB_LR<<3) | |
39 | ||
40 | cfi_offset( d8, JB_D8<<3) | |
41 | cfi_offset( d9, JB_D9<<3) | |
42 | cfi_offset(d10, JB_D10<<3) | |
43 | cfi_offset(d11, JB_D11<<3) | |
44 | cfi_offset(d12, JB_D12<<3) | |
45 | cfi_offset(d13, JB_D13<<3) | |
46 | cfi_offset(d14, JB_D14<<3) | |
47 | cfi_offset(d15, JB_D15<<3) | |
48 | ||
389d1f1b SE |
49 | DELOUSE (0) |
50 | ||
554066b8 MS |
51 | ldp x19, x20, [x0, #JB_X19<<3] |
52 | ldp x21, x22, [x0, #JB_X21<<3] | |
53 | ldp x23, x24, [x0, #JB_X23<<3] | |
54 | ldp x25, x26, [x0, #JB_X25<<3] | |
55 | ldp x27, x28, [x0, #JB_X27<<3] | |
9188b681 VK |
56 | #ifdef PTR_DEMANGLE |
57 | ldp x29, x4, [x0, #JB_X29<<3] | |
389d1f1b | 58 | PTR_DEMANGLE (30, 4, 3, 2) |
9188b681 | 59 | #else |
554066b8 | 60 | ldp x29, x30, [x0, #JB_X29<<3] |
9188b681 | 61 | #endif |
140cc7ab VK |
62 | /* longjmp probe takes 3 arguments, address of jump buffer as |
63 | first argument (8@x0), return value as second argument (-4@x1), | |
64 | and target address (8@x30), respectively. */ | |
65 | LIBC_PROBE (longjmp, 3, 8@x0, -4@x1, 8@x30) | |
554066b8 MS |
66 | ldp d8, d9, [x0, #JB_D8<<3] |
67 | ldp d10, d11, [x0, #JB_D10<<3] | |
68 | ldp d12, d13, [x0, #JB_D12<<3] | |
69 | ldp d14, d15, [x0, #JB_D14<<3] | |
70 | ||
71 | /* Originally this was implemented with a series of | |
72 | .cfi_restore() directives. | |
73 | ||
74 | The theory was that cfi_restore should revert to previous | |
75 | frame value is the same as the current value. In practice | |
76 | this doesn't work, even after cfi_restore() gdb continues | |
77 | to try to recover a previous frame value offset from x0, | |
78 | which gets stuffed after a few more instructions. The | |
79 | cfi_same_value() mechanism appears to work fine. */ | |
80 | ||
81 | cfi_same_value(x19) | |
82 | cfi_same_value(x20) | |
83 | cfi_same_value(x21) | |
84 | cfi_same_value(x22) | |
85 | cfi_same_value(x23) | |
86 | cfi_same_value(x24) | |
87 | cfi_same_value(x25) | |
88 | cfi_same_value(x26) | |
89 | cfi_same_value(x27) | |
90 | cfi_same_value(x28) | |
91 | cfi_same_value(x29) | |
92 | cfi_same_value(x30) | |
93 | cfi_same_value(d8) | |
94 | cfi_same_value(d9) | |
95 | cfi_same_value(d10) | |
96 | cfi_same_value(d11) | |
97 | cfi_same_value(d12) | |
98 | cfi_same_value(d13) | |
99 | cfi_same_value(d14) | |
100 | cfi_same_value(d15) | |
9188b681 VK |
101 | #ifdef PTR_DEMANGLE |
102 | ldr x4, [x0, #JB_SP<<3] | |
389d1f1b | 103 | PTR_DEMANGLE (5, 4, 3, 2) |
9188b681 VK |
104 | #else |
105 | ldr x5, [x0, #JB_SP<<3] | |
106 | #endif | |
554066b8 | 107 | mov sp, x5 |
140cc7ab VK |
108 | |
109 | /* longjmp_target probe takes 3 arguments, address of jump buffer | |
110 | as first argument (8@x0), return value as second argument (-4@x1), | |
111 | and target address (8@x30), respectively. */ | |
112 | LIBC_PROBE (longjmp_target, 3, 8@x0, -4@x1, 8@x30) | |
554066b8 MS |
113 | cmp x1, #0 |
114 | mov x0, #1 | |
115 | csel x0, x1, x0, ne | |
116 | /* Use br instead of ret because ret is guaranteed to mispredict */ | |
117 | br x30 | |
118 | END (__longjmp) |