xref: /aosp_15_r20/external/elfutils/backends/ppc_initreg.c (revision 7304104da70ce23c86437a01be71edd1a2d7f37e)
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 *) &regs;
106*7304104dSAndroid Build Coastguard Worker   struct iovec iovec;
107*7304104dSAndroid Build Coastguard Worker   iovec.iov_base = &regs;
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