]>
Commit | Line | Data |
---|---|---|
b168057a | 1 | /* Copyright (C) 1997-2015 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 | |
17 | <http://www.gnu.org/licenses/>. */ | |
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 | ||
49 | ldp x19, x20, [x0, #JB_X19<<3] | |
50 | ldp x21, x22, [x0, #JB_X21<<3] | |
51 | ldp x23, x24, [x0, #JB_X23<<3] | |
52 | ldp x25, x26, [x0, #JB_X25<<3] | |
53 | ldp x27, x28, [x0, #JB_X27<<3] | |
9188b681 VK |
54 | #ifdef PTR_DEMANGLE |
55 | ldp x29, x4, [x0, #JB_X29<<3] | |
56 | PTR_DEMANGLE (x30, x4, x3, x2) | |
57 | #else | |
554066b8 | 58 | ldp x29, x30, [x0, #JB_X29<<3] |
9188b681 | 59 | #endif |
140cc7ab VK |
60 | /* longjmp probe takes 3 arguments, address of jump buffer as |
61 | first argument (8@x0), return value as second argument (-4@x1), | |
62 | and target address (8@x30), respectively. */ | |
63 | LIBC_PROBE (longjmp, 3, 8@x0, -4@x1, 8@x30) | |
554066b8 MS |
64 | ldp d8, d9, [x0, #JB_D8<<3] |
65 | ldp d10, d11, [x0, #JB_D10<<3] | |
66 | ldp d12, d13, [x0, #JB_D12<<3] | |
67 | ldp d14, d15, [x0, #JB_D14<<3] | |
68 | ||
69 | /* Originally this was implemented with a series of | |
70 | .cfi_restore() directives. | |
71 | ||
72 | The theory was that cfi_restore should revert to previous | |
73 | frame value is the same as the current value. In practice | |
74 | this doesn't work, even after cfi_restore() gdb continues | |
75 | to try to recover a previous frame value offset from x0, | |
76 | which gets stuffed after a few more instructions. The | |
77 | cfi_same_value() mechanism appears to work fine. */ | |
78 | ||
79 | cfi_same_value(x19) | |
80 | cfi_same_value(x20) | |
81 | cfi_same_value(x21) | |
82 | cfi_same_value(x22) | |
83 | cfi_same_value(x23) | |
84 | cfi_same_value(x24) | |
85 | cfi_same_value(x25) | |
86 | cfi_same_value(x26) | |
87 | cfi_same_value(x27) | |
88 | cfi_same_value(x28) | |
89 | cfi_same_value(x29) | |
90 | cfi_same_value(x30) | |
91 | cfi_same_value(d8) | |
92 | cfi_same_value(d9) | |
93 | cfi_same_value(d10) | |
94 | cfi_same_value(d11) | |
95 | cfi_same_value(d12) | |
96 | cfi_same_value(d13) | |
97 | cfi_same_value(d14) | |
98 | cfi_same_value(d15) | |
9188b681 VK |
99 | #ifdef PTR_DEMANGLE |
100 | ldr x4, [x0, #JB_SP<<3] | |
101 | PTR_DEMANGLE (x5, x4, x3, x2) | |
102 | #else | |
103 | ldr x5, [x0, #JB_SP<<3] | |
104 | #endif | |
554066b8 | 105 | mov sp, x5 |
140cc7ab VK |
106 | |
107 | /* longjmp_target probe takes 3 arguments, address of jump buffer | |
108 | as first argument (8@x0), return value as second argument (-4@x1), | |
109 | and target address (8@x30), respectively. */ | |
110 | LIBC_PROBE (longjmp_target, 3, 8@x0, -4@x1, 8@x30) | |
554066b8 MS |
111 | cmp x1, #0 |
112 | mov x0, #1 | |
113 | csel x0, x1, x0, ne | |
114 | /* Use br instead of ret because ret is guaranteed to mispredict */ | |
115 | br x30 | |
116 | END (__longjmp) |