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