Branch data Line data Source code
1 : : /* Fetch live process registers from TID.
2 : : Copyright (C) 2013 Red Hat, Inc.
3 : : Copyright (C) 2022 Mark J. Wielaard <mark@klomp.org>
4 : : This file is part of elfutils.
5 : :
6 : : This file is free software; you can redistribute it and/or modify
7 : : it under the terms of either
8 : :
9 : : * the GNU Lesser General Public License as published by the Free
10 : : Software Foundation; either version 3 of the License, or (at
11 : : your option) any later version
12 : :
13 : : or
14 : :
15 : : * the GNU General Public License as published by the Free
16 : : Software Foundation; either version 2 of the License, or (at
17 : : your option) any later version
18 : :
19 : : or both in parallel, as here.
20 : :
21 : : elfutils is distributed in the hope that it will be useful, but
22 : : WITHOUT ANY WARRANTY; without even the implied warranty of
23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : : General Public License for more details.
25 : :
26 : : You should have received copies of the GNU General Public License and
27 : : the GNU Lesser General Public License along with this program. If
28 : : not, see <http://www.gnu.org/licenses/>. */
29 : :
30 : : #ifdef HAVE_CONFIG_H
31 : : # include <config.h>
32 : : #endif
33 : :
34 : : #include <stdlib.h>
35 : : #if defined(__powerpc__) && defined(__linux__)
36 : : # include <sys/ptrace.h>
37 : : # include <asm/ptrace.h>
38 : : # ifndef PTRACE_GETREGSET
39 : : # include <linux/ptrace.h>
40 : : # endif
41 : : # include <sys/user.h>
42 : : # include <sys/uio.h>
43 : : #endif
44 : :
45 : : #include "system.h"
46 : :
47 : : #define BACKEND ppc_
48 : : #include "libebl_CPU.h"
49 : :
50 : : bool
51 : 2394 : ppc_dwarf_to_regno (Ebl *ebl __attribute__ ((unused)), unsigned *regno)
52 : : {
53 [ + - + + ]: 2394 : switch (*regno)
54 : : {
55 : 16 : case 108:
56 : : // LR uses both 65 and 108 numbers, there is no consistency for it.
57 : 16 : *regno = 65;
58 : 16 : return true;
59 : : case 0 ... 107:
60 : : case 109 ... (114 - 1) -1:
61 : : return true;
62 : 0 : case 1200 ... 1231:
63 : 0 : *regno = *regno - 1200 + (114 - 1);
64 : 0 : return true;
65 : 32 : default:
66 : 32 : return false;
67 : : }
68 : : abort ();
69 : : }
70 : :
71 : : __typeof (ppc_dwarf_to_regno)
72 : : ppc64_dwarf_to_regno
73 : : __attribute__ ((alias ("ppc_dwarf_to_regno")));
74 : :
75 : : bool
76 : 0 : ppc_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
77 : : ebl_tid_registers_t *setfunc __attribute__ ((unused)),
78 : : void *arg __attribute__ ((unused)))
79 : : {
80 : : #if !defined(__powerpc__) || !defined(__linux__)
81 : 0 : return false;
82 : : #else /* __powerpc__ */
83 : :
84 : : /* pt_regs for 32bit processes. Same as 64bit pt_regs but all registers
85 : : are 32bit instead of 64bit long. */
86 : : #define GPRS 32
87 : : struct pt_regs32
88 : : {
89 : : uint32_t gpr[GPRS];
90 : : uint32_t nip;
91 : : uint32_t msr;
92 : : uint32_t orig_gpr3;
93 : : uint32_t ctr;
94 : : uint32_t link;
95 : : uint32_t xer;
96 : : uint32_t ccr;
97 : : uint32_t mq;
98 : : uint32_t trap;
99 : : uint32_t dar;
100 : : uint32_t dsisr;
101 : : uint32_t result;
102 : : };
103 : :
104 : : struct pt_regs regs;
105 : : struct pt_regs32 *regs32 = (struct pt_regs32 *) ®s;
106 : : struct iovec iovec;
107 : : iovec.iov_base = ®s;
108 : : iovec.iov_len = sizeof (regs);
109 : : if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec) != 0)
110 : : return false;
111 : :
112 : : /* Did we get the full pt_regs or less (the 32bit pt_regs)? */
113 : : bool get32 = iovec.iov_len < sizeof (struct pt_regs);
114 : : Dwarf_Word dwarf_regs[GPRS];
115 : : for (unsigned gpr = 0; gpr < GPRS; gpr++)
116 : : dwarf_regs[gpr] = get32 ? regs32->gpr[gpr] : regs.gpr[gpr];
117 : : if (! setfunc (0, GPRS, dwarf_regs, arg))
118 : : return false;
119 : : // LR uses both 65 and 108 numbers, there is no consistency for it.
120 : : Dwarf_Word link = get32 ? regs32->link : regs.link;
121 : : if (! setfunc (65, 1, &link, arg))
122 : : return false;
123 : : /* Registers like msr, ctr, xer, dar, dsisr etc. are probably irrelevant
124 : : for CFI. */
125 : : Dwarf_Word pc = get32 ? (Dwarf_Word) regs32->nip : regs.nip;
126 : : return setfunc (-1, 1, &pc, arg);
127 : : #endif /* __powerpc__ */
128 : : }
129 : :
130 : : __typeof (ppc_set_initial_registers_tid)
131 : : ppc64_set_initial_registers_tid
132 : : __attribute__ ((alias ("ppc_set_initial_registers_tid")));
|