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