Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
a7f0fda0 | 2 | #include <elfutils/libdwfl.h> |
4cb3c6d5 | 3 | #include <linux/kernel.h> |
5cf0e8eb IR |
4 | #include "../../../util/unwind-libdw.h" |
5 | #include "../../../util/perf_regs.h" | |
9823147d | 6 | #include "../../../util/sample.h" |
a7f0fda0 PB |
7 | |
8 | /* See backends/ppc_initreg.c and backends/ppc_regs.c in elfutils. */ | |
9 | static const int special_regs[3][2] = { | |
10 | { 65, PERF_REG_POWERPC_LINK }, | |
11 | { 101, PERF_REG_POWERPC_XER }, | |
12 | { 109, PERF_REG_POWERPC_CTR }, | |
13 | }; | |
14 | ||
15 | bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) | |
16 | { | |
17 | struct unwind_info *ui = arg; | |
18 | struct regs_dump *user_regs = &ui->sample->user_regs; | |
19 | Dwarf_Word dwarf_regs[32], dwarf_nip; | |
20 | size_t i; | |
21 | ||
22 | #define REG(r) ({ \ | |
23 | Dwarf_Word val = 0; \ | |
24 | perf_reg_value(&val, user_regs, PERF_REG_POWERPC_##r); \ | |
25 | val; \ | |
26 | }) | |
27 | ||
28 | dwarf_regs[0] = REG(R0); | |
29 | dwarf_regs[1] = REG(R1); | |
30 | dwarf_regs[2] = REG(R2); | |
31 | dwarf_regs[3] = REG(R3); | |
32 | dwarf_regs[4] = REG(R4); | |
33 | dwarf_regs[5] = REG(R5); | |
34 | dwarf_regs[6] = REG(R6); | |
35 | dwarf_regs[7] = REG(R7); | |
36 | dwarf_regs[8] = REG(R8); | |
37 | dwarf_regs[9] = REG(R9); | |
38 | dwarf_regs[10] = REG(R10); | |
39 | dwarf_regs[11] = REG(R11); | |
40 | dwarf_regs[12] = REG(R12); | |
41 | dwarf_regs[13] = REG(R13); | |
42 | dwarf_regs[14] = REG(R14); | |
43 | dwarf_regs[15] = REG(R15); | |
44 | dwarf_regs[16] = REG(R16); | |
45 | dwarf_regs[17] = REG(R17); | |
46 | dwarf_regs[18] = REG(R18); | |
47 | dwarf_regs[19] = REG(R19); | |
48 | dwarf_regs[20] = REG(R20); | |
49 | dwarf_regs[21] = REG(R21); | |
50 | dwarf_regs[22] = REG(R22); | |
51 | dwarf_regs[23] = REG(R23); | |
52 | dwarf_regs[24] = REG(R24); | |
53 | dwarf_regs[25] = REG(R25); | |
54 | dwarf_regs[26] = REG(R26); | |
55 | dwarf_regs[27] = REG(R27); | |
56 | dwarf_regs[28] = REG(R28); | |
57 | dwarf_regs[29] = REG(R29); | |
58 | dwarf_regs[30] = REG(R30); | |
59 | dwarf_regs[31] = REG(R31); | |
60 | if (!dwfl_thread_state_registers(thread, 0, 32, dwarf_regs)) | |
61 | return false; | |
62 | ||
63 | dwarf_nip = REG(NIP); | |
64 | dwfl_thread_state_register_pc(thread, dwarf_nip); | |
65 | for (i = 0; i < ARRAY_SIZE(special_regs); i++) { | |
66 | Dwarf_Word val = 0; | |
67 | perf_reg_value(&val, user_regs, special_regs[i][1]); | |
68 | if (!dwfl_thread_state_registers(thread, | |
69 | special_regs[i][0], 1, | |
70 | &val)) | |
71 | return false; | |
72 | } | |
73 | ||
74 | return true; | |
75 | } |