Commit | Line | Data |
---|---|---|
45fe57e7 AT |
1 | /* Common target-dependent code for ppc64 GDB, the GNU debugger. |
2 | ||
3666a048 | 3 | Copyright (C) 1986-2021 Free Software Foundation, Inc. |
45fe57e7 AT |
4 | |
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "defs.h" | |
21 | #include "frame.h" | |
22 | #include "gdbcore.h" | |
cf90fd9a | 23 | #include "infrun.h" |
45fe57e7 AT |
24 | #include "ppc-tdep.h" |
25 | #include "ppc64-tdep.h" | |
24c274a1 | 26 | #include "elf-bfd.h" |
45fe57e7 AT |
27 | |
28 | /* Macros for matching instructions. Note that, since all the | |
29 | operands are masked off before they're or-ed into the instruction, | |
30 | you can use -1 to make masks. */ | |
31 | ||
32 | #define insn_d(opcd, rts, ra, d) \ | |
8406672e TT |
33 | ((((unsigned (opcd)) & 0x3f) << 26) \ |
34 | | (((unsigned (rts)) & 0x1f) << 21) \ | |
35 | | (((unsigned (ra)) & 0x1f) << 16) \ | |
36 | | ((unsigned (d)) & 0xffff)) | |
45fe57e7 AT |
37 | |
38 | #define insn_ds(opcd, rts, ra, d, xo) \ | |
8406672e TT |
39 | ((((unsigned (opcd)) & 0x3f) << 26) \ |
40 | | (((unsigned (rts)) & 0x1f) << 21) \ | |
41 | | (((unsigned (ra)) & 0x1f) << 16) \ | |
42 | | ((unsigned (d)) & 0xfffc) \ | |
43 | | ((unsigned (xo)) & 0x3)) | |
45fe57e7 AT |
44 | |
45 | #define insn_xfx(opcd, rts, spr, xo) \ | |
8406672e TT |
46 | ((((unsigned (opcd)) & 0x3f) << 26) \ |
47 | | (((unsigned (rts)) & 0x1f) << 21) \ | |
48 | | (((unsigned (spr)) & 0x1f) << 16) \ | |
49 | | (((unsigned (spr)) & 0x3e0) << 6) \ | |
50 | | (((unsigned (xo)) & 0x3ff) << 1)) | |
45fe57e7 | 51 | |
ecac8d1c CL |
52 | #define prefix(a, b, R, do) \ |
53 | (((0x1) << 26) \ | |
54 | | (((unsigned (a)) & 0x3) << 24) \ | |
55 | | (((unsigned (b)) & 0x1) << 23) \ | |
56 | | (((unsigned (R)) & 0x1) << 20) \ | |
57 | | ((unsigned (do)) & 0x3ffff)) | |
58 | ||
59 | #define insn_md(opcd, ra, rs, sh, me, rc) \ | |
60 | ((((unsigned (opcd)) & 0x3f) << 26) \ | |
61 | | (((unsigned (rs)) & 0x1f) << 21) \ | |
62 | | (((unsigned (ra)) & 0x1f) << 16) \ | |
63 | | (((unsigned (sh)) & 0x3e) << 11) \ | |
64 | | (((unsigned (me)) & 0x3f) << 25) \ | |
65 | | (((unsigned (sh)) & 0x1) << 1) \ | |
66 | | ((unsigned (rc)) & 0x1)) | |
67 | ||
68 | #define insn_x(opcd, rt, ra, rb, opc2) \ | |
69 | ((((unsigned (opcd)) & 0x3f) << 26) \ | |
70 | | (((unsigned (rt)) & 0x1f) << 21) \ | |
71 | | (((unsigned (ra)) & 0x1f) << 16) \ | |
72 | | (((unsigned (rb)) & 0x3e) << 11) \ | |
73 | | (((unsigned (opc2)) & 0x3FF) << 1)) | |
74 | ||
75 | #define insn_xo(opcd, rt, ra, rb, oe, rc, opc2) \ | |
76 | ((((unsigned (opcd)) & 0x3f) << 26) \ | |
77 | | (((unsigned (rt)) & 0x1f) << 21) \ | |
78 | | (((unsigned (ra)) & 0x1f) << 16) \ | |
79 | | (((unsigned (rb)) & 0x3e) << 11) \ | |
80 | | (((unsigned (oe)) & 0x1) << 10) \ | |
81 | | (((unsigned (opc2)) & 0x1FF) << 1) \ | |
82 | | (((unsigned (rc))))) | |
83 | ||
db9077b7 AM |
84 | /* PLT_OFF is the TOC-relative offset of a 64-bit PowerPC PLT entry. |
85 | Return the function's entry point. */ | |
45fe57e7 AT |
86 | |
87 | static CORE_ADDR | |
db9077b7 | 88 | ppc64_plt_entry_point (struct frame_info *frame, CORE_ADDR plt_off) |
45fe57e7 | 89 | { |
db9077b7 | 90 | struct gdbarch *gdbarch = get_frame_arch (frame); |
45fe57e7 | 91 | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); |
db9077b7 AM |
92 | struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); |
93 | CORE_ADDR tocp; | |
94 | ||
95 | if (execution_direction == EXEC_REVERSE) | |
96 | { | |
97 | /* If executing in reverse, r2 will have been stored to the stack. */ | |
98 | CORE_ADDR sp = get_frame_register_unsigned (frame, | |
99 | tdep->ppc_gp0_regnum + 1); | |
100 | unsigned int sp_off = tdep->elf_abi == POWERPC_ELF_V1 ? 40 : 24; | |
101 | tocp = read_memory_unsigned_integer (sp + sp_off, 8, byte_order); | |
102 | } | |
103 | else | |
104 | tocp = get_frame_register_unsigned (frame, tdep->ppc_gp0_regnum + 2); | |
105 | ||
ef1bc9e7 | 106 | /* The first word of the PLT entry is the function entry point. */ |
db9077b7 | 107 | return read_memory_unsigned_integer (tocp + plt_off, 8, byte_order); |
45fe57e7 AT |
108 | } |
109 | ||
ecac8d1c CL |
110 | static CORE_ADDR |
111 | ppc64_plt_pcrel_entry_point (struct frame_info *frame, CORE_ADDR plt_off, | |
112 | CORE_ADDR pc) | |
113 | { | |
114 | struct gdbarch *gdbarch = get_frame_arch (frame); | |
115 | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | |
116 | ||
117 | /* Execution direction doesn't matter, entry is pc + plt_off either way. | |
118 | The first word of the PLT entry is the function entry point. */ | |
119 | return read_memory_unsigned_integer (pc + plt_off, 8, byte_order); | |
120 | } | |
121 | ||
845d4708 AM |
122 | /* Patterns for the standard linkage functions. These are built by |
123 | build_plt_stub in bfd/elf64-ppc.c. */ | |
124 | ||
ef1bc9e7 | 125 | /* Old ELFv1 PLT call stub. */ |
45fe57e7 | 126 | |
7433498b | 127 | static const struct ppc_insn_pattern ppc64_standard_linkage1[] = |
45fe57e7 AT |
128 | { |
129 | /* addis r12, r2, <any> */ | |
130 | { insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 }, | |
131 | ||
132 | /* std r2, 40(r1) */ | |
8406672e | 133 | { (unsigned) -1, insn_ds (62, 2, 1, 40, 0), 0 }, |
45fe57e7 AT |
134 | |
135 | /* ld r11, <any>(r12) */ | |
136 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 }, | |
137 | ||
138 | /* addis r12, r12, 1 <optional> */ | |
139 | { insn_d (-1, -1, -1, -1), insn_d (15, 12, 12, 1), 1 }, | |
140 | ||
141 | /* ld r2, <any>(r12) */ | |
142 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 12, 0, 0), 0 }, | |
143 | ||
144 | /* addis r12, r12, 1 <optional> */ | |
145 | { insn_d (-1, -1, -1, -1), insn_d (15, 12, 12, 1), 1 }, | |
146 | ||
147 | /* mtctr r11 */ | |
148 | { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 }, | |
149 | ||
150 | /* ld r11, <any>(r12) <optional> */ | |
151 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 1 }, | |
152 | ||
153 | /* bctr */ | |
8406672e | 154 | { (unsigned) -1, 0x4e800420, 0 }, |
45fe57e7 AT |
155 | |
156 | { 0, 0, 0 } | |
157 | }; | |
158 | ||
ef1bc9e7 | 159 | /* ELFv1 PLT call stub to access PLT entries more than +/- 32k from r2. |
845d4708 AM |
160 | Also supports older stub with different placement of std 2,40(1), |
161 | a stub that omits the std 2,40(1), and both versions of power7 | |
162 | thread safety read barriers. Note that there are actually two more | |
163 | instructions following "cmpldi r2, 0", "bnectr+" and "b <glink_i>", | |
164 | but there isn't any need to match them. */ | |
45fe57e7 | 165 | |
7433498b | 166 | static const struct ppc_insn_pattern ppc64_standard_linkage2[] = |
45fe57e7 | 167 | { |
845d4708 | 168 | /* std r2, 40(r1) <optional> */ |
8406672e | 169 | { (unsigned) -1, insn_ds (62, 2, 1, 40, 0), 1 }, |
845d4708 | 170 | |
45fe57e7 AT |
171 | /* addis r12, r2, <any> */ |
172 | { insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 }, | |
173 | ||
845d4708 | 174 | /* std r2, 40(r1) <optional> */ |
8406672e | 175 | { (unsigned) -1, insn_ds (62, 2, 1, 40, 0), 1 }, |
45fe57e7 AT |
176 | |
177 | /* ld r11, <any>(r12) */ | |
178 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 }, | |
179 | ||
180 | /* addi r12, r12, <any> <optional> */ | |
181 | { insn_d (-1, -1, -1, 0), insn_d (14, 12, 12, 0), 1 }, | |
182 | ||
183 | /* mtctr r11 */ | |
184 | { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 }, | |
185 | ||
845d4708 | 186 | /* xor r11, r11, r11 <optional> */ |
8406672e | 187 | { (unsigned) -1, 0x7d6b5a78, 1 }, |
845d4708 AM |
188 | |
189 | /* add r12, r12, r11 <optional> */ | |
8406672e | 190 | { (unsigned) -1, 0x7d8c5a14, 1 }, |
845d4708 | 191 | |
45fe57e7 AT |
192 | /* ld r2, <any>(r12) */ |
193 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 12, 0, 0), 0 }, | |
194 | ||
195 | /* ld r11, <any>(r12) <optional> */ | |
196 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 1 }, | |
197 | ||
845d4708 | 198 | /* bctr <optional> */ |
8406672e | 199 | { (unsigned) -1, 0x4e800420, 1 }, |
845d4708 AM |
200 | |
201 | /* cmpldi r2, 0 <optional> */ | |
8406672e | 202 | { (unsigned) -1, 0x28220000, 1 }, |
45fe57e7 AT |
203 | |
204 | { 0, 0, 0 } | |
205 | }; | |
206 | ||
ef1bc9e7 | 207 | /* ELFv1 PLT call stub to access PLT entries within +/- 32k of r2. */ |
45fe57e7 | 208 | |
7433498b | 209 | static const struct ppc_insn_pattern ppc64_standard_linkage3[] = |
45fe57e7 | 210 | { |
845d4708 | 211 | /* std r2, 40(r1) <optional> */ |
8406672e | 212 | { (unsigned) -1, insn_ds (62, 2, 1, 40, 0), 1 }, |
45fe57e7 AT |
213 | |
214 | /* ld r11, <any>(r2) */ | |
215 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 0 }, | |
216 | ||
217 | /* addi r2, r2, <any> <optional> */ | |
218 | { insn_d (-1, -1, -1, 0), insn_d (14, 2, 2, 0), 1 }, | |
219 | ||
220 | /* mtctr r11 */ | |
221 | { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 }, | |
222 | ||
845d4708 | 223 | /* xor r11, r11, r11 <optional> */ |
8406672e | 224 | { (unsigned) -1, 0x7d6b5a78, 1 }, |
845d4708 AM |
225 | |
226 | /* add r2, r2, r11 <optional> */ | |
8406672e | 227 | { (unsigned) -1, 0x7c425a14, 1 }, |
845d4708 | 228 | |
45fe57e7 AT |
229 | /* ld r11, <any>(r2) <optional> */ |
230 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 1 }, | |
231 | ||
232 | /* ld r2, <any>(r2) */ | |
233 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 2, 0, 0), 0 }, | |
234 | ||
845d4708 | 235 | /* bctr <optional> */ |
8406672e | 236 | { (unsigned) -1, 0x4e800420, 1 }, |
845d4708 AM |
237 | |
238 | /* cmpldi r2, 0 <optional> */ | |
8406672e | 239 | { (unsigned) -1, 0x28220000, 1 }, |
45fe57e7 AT |
240 | |
241 | { 0, 0, 0 } | |
242 | }; | |
243 | ||
ef1bc9e7 AM |
244 | /* ELFv1 PLT call stub to access PLT entries more than +/- 32k from r2. |
245 | A more modern variant of ppc64_standard_linkage2 differing in | |
246 | register usage. */ | |
247 | ||
7433498b | 248 | static const struct ppc_insn_pattern ppc64_standard_linkage4[] = |
ef1bc9e7 AM |
249 | { |
250 | /* std r2, 40(r1) <optional> */ | |
8406672e | 251 | { (unsigned) -1, insn_ds (62, 2, 1, 40, 0), 1 }, |
ef1bc9e7 AM |
252 | |
253 | /* addis r11, r2, <any> */ | |
254 | { insn_d (-1, -1, -1, 0), insn_d (15, 11, 2, 0), 0 }, | |
255 | ||
256 | /* ld r12, <any>(r11) */ | |
257 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 11, 0, 0), 0 }, | |
258 | ||
259 | /* addi r11, r11, <any> <optional> */ | |
260 | { insn_d (-1, -1, -1, 0), insn_d (14, 11, 11, 0), 1 }, | |
261 | ||
262 | /* mtctr r12 */ | |
263 | { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, | |
264 | ||
265 | /* xor r2, r12, r12 <optional> */ | |
8406672e | 266 | { (unsigned) -1, 0x7d826278, 1 }, |
ef1bc9e7 AM |
267 | |
268 | /* add r11, r11, r2 <optional> */ | |
8406672e | 269 | { (unsigned) -1, 0x7d6b1214, 1 }, |
ef1bc9e7 AM |
270 | |
271 | /* ld r2, <any>(r11) */ | |
272 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 11, 0, 0), 0 }, | |
273 | ||
274 | /* ld r11, <any>(r11) <optional> */ | |
275 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 11, 0, 0), 1 }, | |
276 | ||
277 | /* bctr <optional> */ | |
8406672e | 278 | { (unsigned) -1, 0x4e800420, 1 }, |
ef1bc9e7 AM |
279 | |
280 | /* cmpldi r2, 0 <optional> */ | |
8406672e | 281 | { (unsigned) -1, 0x28220000, 1 }, |
ef1bc9e7 AM |
282 | |
283 | { 0, 0, 0 } | |
284 | }; | |
285 | ||
286 | /* ELFv1 PLT call stub to access PLT entries within +/- 32k of r2. | |
287 | A more modern variant of ppc64_standard_linkage3 differing in | |
288 | register usage. */ | |
289 | ||
7433498b | 290 | static const struct ppc_insn_pattern ppc64_standard_linkage5[] = |
ef1bc9e7 AM |
291 | { |
292 | /* std r2, 40(r1) <optional> */ | |
8406672e | 293 | { (unsigned) -1, insn_ds (62, 2, 1, 40, 0), 1 }, |
ef1bc9e7 AM |
294 | |
295 | /* ld r12, <any>(r2) */ | |
296 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 2, 0, 0), 0 }, | |
297 | ||
298 | /* addi r2, r2, <any> <optional> */ | |
299 | { insn_d (-1, -1, -1, 0), insn_d (14, 2, 2, 0), 1 }, | |
300 | ||
301 | /* mtctr r12 */ | |
302 | { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, | |
303 | ||
304 | /* xor r11, r12, r12 <optional> */ | |
8406672e | 305 | { (unsigned) -1, 0x7d8b6278, 1 }, |
ef1bc9e7 AM |
306 | |
307 | /* add r2, r2, r11 <optional> */ | |
8406672e | 308 | { (unsigned) -1, 0x7c425a14, 1 }, |
ef1bc9e7 AM |
309 | |
310 | /* ld r11, <any>(r2) <optional> */ | |
311 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 1 }, | |
312 | ||
313 | /* ld r2, <any>(r2) */ | |
314 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 2, 0, 0), 0 }, | |
315 | ||
316 | /* bctr <optional> */ | |
8406672e | 317 | { (unsigned) -1, 0x4e800420, 1 }, |
ef1bc9e7 AM |
318 | |
319 | /* cmpldi r2, 0 <optional> */ | |
8406672e | 320 | { (unsigned) -1, 0x28220000, 1 }, |
ef1bc9e7 AM |
321 | |
322 | { 0, 0, 0 } | |
323 | }; | |
324 | ||
325 | /* ELFv2 PLT call stub to access PLT entries more than +/- 32k from r2. */ | |
326 | ||
7433498b | 327 | static const struct ppc_insn_pattern ppc64_standard_linkage6[] = |
ef1bc9e7 AM |
328 | { |
329 | /* std r2, 24(r1) <optional> */ | |
8406672e | 330 | { (unsigned) -1, insn_ds (62, 2, 1, 24, 0), 1 }, |
ef1bc9e7 AM |
331 | |
332 | /* addis r11, r2, <any> */ | |
333 | { insn_d (-1, -1, -1, 0), insn_d (15, 11, 2, 0), 0 }, | |
334 | ||
335 | /* ld r12, <any>(r11) */ | |
336 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 11, 0, 0), 0 }, | |
337 | ||
338 | /* mtctr r12 */ | |
339 | { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, | |
340 | ||
341 | /* bctr */ | |
8406672e | 342 | { (unsigned) -1, 0x4e800420, 0 }, |
ef1bc9e7 AM |
343 | |
344 | { 0, 0, 0 } | |
345 | }; | |
346 | ||
347 | /* ELFv2 PLT call stub to access PLT entries within +/- 32k of r2. */ | |
348 | ||
7433498b | 349 | static const struct ppc_insn_pattern ppc64_standard_linkage7[] = |
ef1bc9e7 AM |
350 | { |
351 | /* std r2, 24(r1) <optional> */ | |
8406672e | 352 | { (unsigned) -1, insn_ds (62, 2, 1, 24, 0), 1 }, |
ef1bc9e7 AM |
353 | |
354 | /* ld r12, <any>(r2) */ | |
355 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 2, 0, 0), 0 }, | |
356 | ||
357 | /* mtctr r12 */ | |
358 | { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, | |
359 | ||
360 | /* bctr */ | |
8406672e | 361 | { (unsigned) -1, 0x4e800420, 0 }, |
ef1bc9e7 AM |
362 | |
363 | { 0, 0, 0 } | |
364 | }; | |
365 | ||
397998fc AM |
366 | /* ELFv2 PLT call stub to access PLT entries more than +/- 32k from r2, |
367 | supporting fusion. */ | |
368 | ||
7433498b | 369 | static const struct ppc_insn_pattern ppc64_standard_linkage8[] = |
397998fc AM |
370 | { |
371 | /* std r2, 24(r1) <optional> */ | |
8406672e | 372 | { (unsigned) -1, insn_ds (62, 2, 1, 24, 0), 1 }, |
397998fc AM |
373 | |
374 | /* addis r12, r2, <any> */ | |
375 | { insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 }, | |
376 | ||
377 | /* ld r12, <any>(r12) */ | |
378 | { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 12, 0, 0), 0 }, | |
379 | ||
380 | /* mtctr r12 */ | |
381 | { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, | |
382 | ||
383 | /* bctr */ | |
8406672e | 384 | { (unsigned) -1, 0x4e800420, 0 }, |
397998fc AM |
385 | |
386 | { 0, 0, 0 } | |
387 | }; | |
388 | ||
ecac8d1c CL |
389 | /* Power 10 ELFv2 PLT call stubs */ |
390 | static const struct ppc_insn_pattern ppc64_standard_linkage9[] = | |
391 | { | |
392 | /* std %r2,0+40(%r1) <optional> */ | |
393 | { insn_ds (-1, -1, -1, 0, 1), insn_ds (62, 2, 1, 40, 0), 1 }, | |
394 | ||
395 | /* pld r12, <any> */ | |
396 | { prefix (-1, -1, 1, 0), prefix (0, 0, 1, 0), 0 }, | |
397 | { insn_d (-1, -1, -1, 0), insn_d (57, 12, 0, 0), 0 }, | |
398 | ||
399 | /* mtctr r12 */ | |
400 | { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, | |
401 | ||
402 | /* bctr */ | |
403 | { (unsigned) -1, 0x4e800420, 0 }, | |
404 | ||
405 | { 0, 0, 0 } | |
406 | }; | |
407 | ||
408 | static const struct ppc_insn_pattern ppc64_standard_linkage10[] = | |
409 | { | |
410 | /* std %r2,0+40(%r1) <optional> */ | |
411 | { insn_ds (-1, -1, -1, 0, 1), insn_ds (62, 2, 1, 40, 0), 1 }, | |
412 | ||
413 | /* paddi r12,<any> */ | |
414 | { prefix (-1, -1, 1, 0), prefix (2, 0, 1, 0), 0 }, | |
415 | { insn_d (-1, -1, -1, 0), insn_d (14, 12, 0, 0), 0 }, | |
416 | ||
417 | /* mtctr r12 <optional> */ | |
418 | { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, | |
419 | ||
420 | /* bctr */ | |
421 | { (unsigned) -1, 0x4e800420, 0 }, | |
422 | ||
423 | { 0, 0, 0 } | |
424 | }; | |
425 | ||
426 | static const struct ppc_insn_pattern ppc64_standard_linkage11[] = | |
427 | { | |
428 | /* std %r2,0+40(%r1) <optional> */ | |
429 | { insn_ds (-1, -1, -1, 0, 1), insn_ds (62, 2, 1, 40, 0), 1 }, | |
430 | ||
431 | /* li %r11,0 <optional> */ | |
432 | { insn_d (-1, -1, -1, 0), insn_d (14, 11, 0, 0), 1 }, | |
433 | ||
434 | /* sldi %r11,%r11,34 <eq to rldicr rx,ry,n, 63-n> <optional> */ | |
435 | { insn_md (-1, -1, -1, 0, 0, 1), insn_md (30, 11, 11, 34, 63-34, 0), 1 }, | |
436 | ||
437 | /* paddi r12, <any> */ | |
438 | { prefix (-1, -1, 1, 0), prefix (2, 0, 1, 0), 0 }, | |
439 | { insn_d (-1, -1, -1, 0), insn_d (14, 12, 0, 0), 0 }, | |
440 | ||
441 | /* ldx %r12,%r11,%r12 <optional> */ | |
442 | { (unsigned) -1, insn_x (31, 12, 11, 12, 21), 1 }, | |
443 | ||
444 | /* add %r12,%r11,%r12 <optional> */ | |
445 | { (unsigned) -1, insn_xo (31, 12, 11, 12, 0, 0, 40), 1 }, | |
446 | ||
447 | /* mtctr r12 */ | |
448 | { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, | |
449 | ||
450 | /* bctr */ // 13, 14, 15, 16 | |
451 | { (unsigned) -1, 0x4e800420, 0 }, | |
452 | ||
453 | { 0, 0, 0 } | |
454 | }; | |
455 | ||
456 | static const struct ppc_insn_pattern ppc64_standard_linkage12[] = | |
457 | { | |
458 | /* std %r2,0+40(%r1) <optional> */ | |
459 | { insn_ds (-1, -1, -1, 0, 1), insn_ds (62, 2, 1, 40, 0), 1 }, | |
460 | ||
461 | /* lis %r11,xxx@ha <equivalent addis rx, 0, val> */ | |
462 | /* addis r12, r2, <any> */ | |
463 | { insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 }, | |
464 | ||
465 | /* ori %r11,%r11,xxx@l */ | |
466 | { insn_d (-1, -1, -1, 0), insn_d (24, 11, 11, 0), 0 }, | |
467 | ||
468 | /* sldi %r11,%r11,34 <optional> */ | |
469 | { (unsigned) -1, insn_md (30, 11, 11, 34, 63-34, 0), 1 }, | |
470 | ||
471 | /*paddi r12,<any> */ | |
472 | { prefix (-1, -1, 1, 0), prefix (2, 0, 1, 0), 0 }, | |
473 | { insn_d (-1, -1, -1, 0), insn_d (14, 12, 0, 0), 0 }, | |
474 | ||
475 | /* sldi %r11,%r11,34 <optional> */ | |
476 | { (unsigned) -1, insn_md (30, 11, 11, 34, 63-34, 0), 1 }, | |
477 | ||
478 | /* ldx %r12,%r11,%r12 <optional> */ | |
479 | { (unsigned) -1, insn_x (31, 12, 11, 12, 21), 1 }, | |
480 | ||
481 | /* add %r12,%r11,%r12 <optional> */ | |
482 | { (unsigned) -1, insn_xo (31, 12, 11, 12, 0, 0, 40), 1 }, | |
483 | ||
484 | /* mtctr r12 */ | |
485 | { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, | |
486 | ||
487 | /* bctr */ // 17, 18, 19, 20 | |
488 | { (unsigned) -1, 0x4e800420, 0 }, | |
489 | ||
490 | { 0, 0, 0 } | |
491 | }; | |
492 | ||
45fe57e7 AT |
493 | /* When the dynamic linker is doing lazy symbol resolution, the first |
494 | call to a function in another object will go like this: | |
495 | ||
496 | - The user's function calls the linkage function: | |
497 | ||
845d4708 AM |
498 | 100003d4: 4b ff ff ad bl 10000380 <nnnn.plt_call.printf> |
499 | 100003d8: e8 41 00 28 ld r2,40(r1) | |
45fe57e7 | 500 | |
845d4708 AM |
501 | - The linkage function loads the entry point and toc pointer from |
502 | the function descriptor in the PLT, and jumps to it: | |
45fe57e7 | 503 | |
845d4708 AM |
504 | <nnnn.plt_call.printf>: |
505 | 10000380: f8 41 00 28 std r2,40(r1) | |
506 | 10000384: e9 62 80 78 ld r11,-32648(r2) | |
507 | 10000388: 7d 69 03 a6 mtctr r11 | |
508 | 1000038c: e8 42 80 80 ld r2,-32640(r2) | |
509 | 10000390: 28 22 00 00 cmpldi r2,0 | |
510 | 10000394: 4c e2 04 20 bnectr+ | |
511 | 10000398: 48 00 03 a0 b 10000738 <printf@plt> | |
45fe57e7 AT |
512 | |
513 | - But since this is the first time that PLT entry has been used, it | |
845d4708 AM |
514 | sends control to its glink entry. That loads the number of the |
515 | PLT entry and jumps to the common glink0 code: | |
45fe57e7 | 516 | |
845d4708 AM |
517 | <printf@plt>: |
518 | 10000738: 38 00 00 01 li r0,1 | |
519 | 1000073c: 4b ff ff bc b 100006f8 <__glink_PLTresolve> | |
45fe57e7 AT |
520 | |
521 | - The common glink0 code then transfers control to the dynamic | |
845d4708 AM |
522 | linker's fixup code: |
523 | ||
524 | 100006f0: 0000000000010440 .quad plt0 - (. + 16) | |
525 | <__glink_PLTresolve>: | |
526 | 100006f8: 7d 88 02 a6 mflr r12 | |
527 | 100006fc: 42 9f 00 05 bcl 20,4*cr7+so,10000700 | |
528 | 10000700: 7d 68 02 a6 mflr r11 | |
529 | 10000704: e8 4b ff f0 ld r2,-16(r11) | |
530 | 10000708: 7d 88 03 a6 mtlr r12 | |
531 | 1000070c: 7d 82 5a 14 add r12,r2,r11 | |
532 | 10000710: e9 6c 00 00 ld r11,0(r12) | |
533 | 10000714: e8 4c 00 08 ld r2,8(r12) | |
534 | 10000718: 7d 69 03 a6 mtctr r11 | |
535 | 1000071c: e9 6c 00 10 ld r11,16(r12) | |
536 | 10000720: 4e 80 04 20 bctr | |
45fe57e7 AT |
537 | |
538 | Eventually, this code will figure out how to skip all of this, | |
539 | including the dynamic linker. At the moment, we just get through | |
540 | the linkage function. */ | |
541 | ||
542 | /* If the current thread is about to execute a series of instructions | |
db9077b7 | 543 | matching the ppc64_standard_linkage pattern, and INSN is the result |
45fe57e7 AT |
544 | from that pattern match, return the code address to which the |
545 | standard linkage function will send them. (This doesn't deal with | |
546 | dynamic linker lazy symbol resolution stubs.) */ | |
547 | ||
548 | static CORE_ADDR | |
db9077b7 | 549 | ppc64_standard_linkage1_target (struct frame_info *frame, unsigned int *insn) |
45fe57e7 | 550 | { |
db9077b7 AM |
551 | CORE_ADDR plt_off = ((ppc_insn_d_field (insn[0]) << 16) |
552 | + ppc_insn_ds_field (insn[2])); | |
45fe57e7 | 553 | |
db9077b7 | 554 | return ppc64_plt_entry_point (frame, plt_off); |
45fe57e7 AT |
555 | } |
556 | ||
557 | static CORE_ADDR | |
db9077b7 | 558 | ppc64_standard_linkage2_target (struct frame_info *frame, unsigned int *insn) |
45fe57e7 | 559 | { |
db9077b7 AM |
560 | CORE_ADDR plt_off = ((ppc_insn_d_field (insn[1]) << 16) |
561 | + ppc_insn_ds_field (insn[3])); | |
45fe57e7 | 562 | |
db9077b7 | 563 | return ppc64_plt_entry_point (frame, plt_off); |
45fe57e7 AT |
564 | } |
565 | ||
566 | static CORE_ADDR | |
db9077b7 | 567 | ppc64_standard_linkage3_target (struct frame_info *frame, unsigned int *insn) |
45fe57e7 | 568 | { |
db9077b7 | 569 | CORE_ADDR plt_off = ppc_insn_ds_field (insn[1]); |
45fe57e7 | 570 | |
db9077b7 | 571 | return ppc64_plt_entry_point (frame, plt_off); |
ef1bc9e7 AM |
572 | } |
573 | ||
574 | static CORE_ADDR | |
db9077b7 | 575 | ppc64_standard_linkage4_target (struct frame_info *frame, unsigned int *insn) |
ef1bc9e7 | 576 | { |
db9077b7 AM |
577 | CORE_ADDR plt_off = ((ppc_insn_d_field (insn[1]) << 16) |
578 | + ppc_insn_ds_field (insn[2])); | |
ef1bc9e7 | 579 | |
db9077b7 | 580 | return ppc64_plt_entry_point (frame, plt_off); |
45fe57e7 AT |
581 | } |
582 | ||
ecac8d1c CL |
583 | static CORE_ADDR |
584 | ppc64_pcrel_linkage1_target (struct frame_info *frame, unsigned int *insn, | |
585 | CORE_ADDR pc) | |
586 | { | |
587 | /* insn[0] is for the std instruction. */ | |
588 | CORE_ADDR plt_off = ppc_insn_prefix_dform (insn[1], insn[2]); | |
589 | ||
590 | return ppc64_plt_pcrel_entry_point (frame, plt_off, pc); | |
591 | } | |
592 | ||
593 | static CORE_ADDR | |
594 | ppc64_pcrel_linkage2_target (struct frame_info *frame, unsigned int *insn, | |
595 | CORE_ADDR pc) | |
596 | { | |
597 | CORE_ADDR plt_off; | |
598 | ||
599 | /* insn[0] is for the std instruction. | |
600 | insn[1] is for the li r11 instruction */ | |
601 | plt_off = ppc_insn_prefix_dform (insn[2], insn[3]); | |
602 | ||
603 | return ppc64_plt_pcrel_entry_point (frame, plt_off, pc); | |
604 | } | |
605 | ||
45fe57e7 AT |
606 | |
607 | /* Given that we've begun executing a call trampoline at PC, return | |
ddeca1df WW |
608 | the entry point of the function the trampoline will go to. |
609 | ||
610 | When the execution direction is EXEC_REVERSE, scan backward to | |
611 | check whether we are in the middle of a PLT stub. */ | |
45fe57e7 | 612 | |
141c5cc4 JK |
613 | static CORE_ADDR |
614 | ppc64_skip_trampoline_code_1 (struct frame_info *frame, CORE_ADDR pc) | |
45fe57e7 | 615 | { |
845d4708 | 616 | #define MAX(a,b) ((a) > (b) ? (a) : (b)) |
ef1bc9e7 AM |
617 | unsigned int insns[MAX (MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1), |
618 | ARRAY_SIZE (ppc64_standard_linkage2)), | |
619 | MAX (ARRAY_SIZE (ppc64_standard_linkage3), | |
620 | ARRAY_SIZE (ppc64_standard_linkage4))), | |
ecac8d1c | 621 | MAX(MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage5), |
ef1bc9e7 | 622 | ARRAY_SIZE (ppc64_standard_linkage6)), |
397998fc | 623 | MAX (ARRAY_SIZE (ppc64_standard_linkage7), |
ecac8d1c CL |
624 | ARRAY_SIZE (ppc64_standard_linkage8))), |
625 | MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage9), | |
626 | ARRAY_SIZE (ppc64_standard_linkage10)), | |
627 | MAX (ARRAY_SIZE (ppc64_standard_linkage11), | |
628 | ARRAY_SIZE (ppc64_standard_linkage12))))) | |
629 | ||
397998fc | 630 | - 1]; |
45fe57e7 | 631 | CORE_ADDR target; |
cf90fd9a WW |
632 | int scan_limit, i; |
633 | ||
634 | scan_limit = 1; | |
635 | /* When reverse-debugging, scan backward to check whether we are | |
636 | in the middle of trampoline code. */ | |
637 | if (execution_direction == EXEC_REVERSE) | |
638 | scan_limit = ARRAY_SIZE (insns) - 1; | |
639 | ||
640 | for (i = 0; i < scan_limit; i++) | |
641 | { | |
ecac8d1c CL |
642 | if (i < ARRAY_SIZE (ppc64_standard_linkage12) - 1 |
643 | && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage12, insns)) | |
644 | pc = ppc64_pcrel_linkage1_target (frame, insns, pc); | |
645 | else if (i < ARRAY_SIZE (ppc64_standard_linkage11) - 1 | |
646 | && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage11, insns)) | |
647 | pc = ppc64_pcrel_linkage2_target (frame, insns, pc); | |
648 | else if (i < ARRAY_SIZE (ppc64_standard_linkage10) - 1 | |
649 | && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage10, insns)) | |
650 | pc = ppc64_pcrel_linkage1_target (frame, insns, pc); | |
651 | else if (i < ARRAY_SIZE (ppc64_standard_linkage9) - 1 | |
652 | && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage9, insns)) | |
653 | pc = ppc64_pcrel_linkage1_target (frame, insns, pc); | |
654 | else if (i < ARRAY_SIZE (ppc64_standard_linkage8) - 1 | |
cf90fd9a | 655 | && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns)) |
db9077b7 | 656 | pc = ppc64_standard_linkage4_target (frame, insns); |
cf90fd9a WW |
657 | else if (i < ARRAY_SIZE (ppc64_standard_linkage7) - 1 |
658 | && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7, | |
659 | insns)) | |
db9077b7 | 660 | pc = ppc64_standard_linkage3_target (frame, insns); |
cf90fd9a WW |
661 | else if (i < ARRAY_SIZE (ppc64_standard_linkage6) - 1 |
662 | && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6, | |
663 | insns)) | |
db9077b7 | 664 | pc = ppc64_standard_linkage4_target (frame, insns); |
cf90fd9a WW |
665 | else if (i < ARRAY_SIZE (ppc64_standard_linkage5) - 1 |
666 | && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5, | |
667 | insns) | |
668 | && (insns[8] != 0 || insns[9] != 0)) | |
db9077b7 | 669 | pc = ppc64_standard_linkage3_target (frame, insns); |
cf90fd9a WW |
670 | else if (i < ARRAY_SIZE (ppc64_standard_linkage4) - 1 |
671 | && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4, | |
672 | insns) | |
673 | && (insns[9] != 0 || insns[10] != 0)) | |
db9077b7 | 674 | pc = ppc64_standard_linkage4_target (frame, insns); |
cf90fd9a WW |
675 | else if (i < ARRAY_SIZE (ppc64_standard_linkage3) - 1 |
676 | && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, | |
677 | insns) | |
678 | && (insns[8] != 0 || insns[9] != 0)) | |
db9077b7 | 679 | pc = ppc64_standard_linkage3_target (frame, insns); |
cf90fd9a WW |
680 | else if (i < ARRAY_SIZE (ppc64_standard_linkage2) - 1 |
681 | && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, | |
682 | insns) | |
683 | && (insns[10] != 0 || insns[11] != 0)) | |
db9077b7 | 684 | pc = ppc64_standard_linkage2_target (frame, insns); |
cf90fd9a WW |
685 | else if (i < ARRAY_SIZE (ppc64_standard_linkage1) - 1 |
686 | && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1, | |
687 | insns)) | |
db9077b7 | 688 | pc = ppc64_standard_linkage1_target (frame, insns); |
cf90fd9a WW |
689 | else |
690 | { | |
691 | /* Scan backward one more instructions if doesn't match. */ | |
692 | pc -= 4; | |
693 | continue; | |
694 | } | |
695 | ||
696 | /* The PLT descriptor will either point to the already resolved target | |
dda83cd7 SM |
697 | address, or else to a glink stub. As the latter carry synthetic @plt |
698 | symbols, find_solib_trampoline_target should be able to resolve them. */ | |
cf90fd9a WW |
699 | target = find_solib_trampoline_target (frame, pc); |
700 | return target ? target : pc; | |
701 | } | |
702 | ||
703 | return 0; | |
45fe57e7 AT |
704 | } |
705 | ||
141c5cc4 JK |
706 | /* Wrapper of ppc64_skip_trampoline_code_1 checking also |
707 | ppc_elfv2_skip_entrypoint. */ | |
708 | ||
709 | CORE_ADDR | |
710 | ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) | |
711 | { | |
712 | struct gdbarch *gdbarch = get_frame_arch (frame); | |
713 | ||
714 | pc = ppc64_skip_trampoline_code_1 (frame, pc); | |
715 | if (pc != 0 && gdbarch_skip_entrypoint_p (gdbarch)) | |
716 | pc = gdbarch_skip_entrypoint (gdbarch, pc); | |
717 | return pc; | |
718 | } | |
719 | ||
45fe57e7 AT |
720 | /* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC64 |
721 | GNU/Linux. | |
722 | ||
723 | Usually a function pointer's representation is simply the address | |
724 | of the function. On GNU/Linux on the PowerPC however, a function | |
725 | pointer may be a pointer to a function descriptor. | |
726 | ||
727 | For PPC64, a function descriptor is a TOC entry, in a data section, | |
728 | which contains three words: the first word is the address of the | |
729 | function, the second word is the TOC pointer (r2), and the third word | |
730 | is the static chain value. | |
731 | ||
732 | Throughout GDB it is currently assumed that a function pointer contains | |
733 | the address of the function, which is not easy to fix. In addition, the | |
734 | conversion of a function address to a function pointer would | |
735 | require allocation of a TOC entry in the inferior's memory space, | |
736 | with all its drawbacks. To be able to call C++ virtual methods in | |
737 | the inferior (which are called via function pointers), | |
738 | find_function_addr uses this function to get the function address | |
739 | from a function pointer. | |
740 | ||
741 | If ADDR points at what is clearly a function descriptor, transform | |
742 | it into the address of the corresponding function, if needed. Be | |
743 | conservative, otherwise GDB will do the transformation on any | |
744 | random addresses such as occur when there is no symbol table. */ | |
745 | ||
746 | CORE_ADDR | |
747 | ppc64_convert_from_func_ptr_addr (struct gdbarch *gdbarch, | |
748 | CORE_ADDR addr, | |
749 | struct target_ops *targ) | |
750 | { | |
751 | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | |
19cf757a | 752 | const struct target_section *s = target_section_by_addr (targ, addr); |
45fe57e7 AT |
753 | |
754 | /* Check if ADDR points to a function descriptor. */ | |
755 | if (s && strcmp (s->the_bfd_section->name, ".opd") == 0) | |
756 | { | |
757 | /* There may be relocations that need to be applied to the .opd | |
758 | section. Unfortunately, this function may be called at a time | |
759 | where these relocations have not yet been performed -- this can | |
760 | happen for example shortly after a library has been loaded with | |
761 | dlopen, but ld.so has not yet applied the relocations. | |
762 | ||
763 | To cope with both the case where the relocation has been applied, | |
764 | and the case where it has not yet been applied, we do *not* read | |
765 | the (maybe) relocated value from target memory, but we instead | |
766 | read the non-relocated value from the BFD, and apply the relocation | |
767 | offset manually. | |
768 | ||
769 | This makes the assumption that all .opd entries are always relocated | |
770 | by the same offset the section itself was relocated. This should | |
771 | always be the case for GNU/Linux executables and shared libraries. | |
772 | Note that other kind of object files (e.g. those added via | |
773 | add-symbol-files) will currently never end up here anyway, as this | |
774 | function accesses *target* sections only; only the main exec and | |
775 | shared libraries are ever added to the target. */ | |
776 | ||
777 | gdb_byte buf[8]; | |
778 | int res; | |
779 | ||
57e6060e DE |
780 | res = bfd_get_section_contents (s->the_bfd_section->owner, |
781 | s->the_bfd_section, | |
45fe57e7 AT |
782 | &buf, addr - s->addr, 8); |
783 | if (res != 0) | |
fd361982 AM |
784 | return (extract_unsigned_integer (buf, 8, byte_order) |
785 | - bfd_section_vma (s->the_bfd_section) + s->addr); | |
45fe57e7 AT |
786 | } |
787 | ||
788 | return addr; | |
789 | } | |
24c274a1 AM |
790 | |
791 | /* A synthetic 'dot' symbols on ppc64 has the udata.p entry pointing | |
792 | back to the original ELF symbol it was derived from. Get the size | |
793 | from that symbol. */ | |
794 | ||
795 | void | |
796 | ppc64_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym) | |
797 | { | |
798 | if ((sym->flags & BSF_SYNTHETIC) != 0 && sym->udata.p != NULL) | |
799 | { | |
800 | elf_symbol_type *elf_sym = (elf_symbol_type *) sym->udata.p; | |
801 | SET_MSYMBOL_SIZE (msym, elf_sym->internal_elf_sym.st_size); | |
802 | } | |
803 | } |