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 "system.h" 34 #include <stdlib.h> 35 #ifdef __powerpc__ 36 # include <sys/user.h> 37 # include <sys/ptrace.h> 38 #endif 39 40 #define BACKEND ppc_ 41 #include "libebl_CPU.h" 42 43 bool 44 ppc_dwarf_to_regno (Ebl *ebl __attribute__ ((unused)), unsigned *regno) 45 { 46 switch (*regno) 47 { 48 case 108: 49 // LR uses both 65 and 108 numbers, there is no consistency for it. 50 *regno = 65; 51 return true; 52 case 0 ... 107: 53 case 109 ... (114 - 1) -1: 54 return true; 55 case 1200 ... 1231: 56 *regno = *regno - 1200 + (114 - 1); 57 return true; 58 default: 59 return false; 60 } 61 abort (); 62 } 63 64 __typeof (ppc_dwarf_to_regno) 65 ppc64_dwarf_to_regno 66 __attribute__ ((alias ("ppc_dwarf_to_regno"))); 67 68 bool 69 ppc_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), 70 ebl_tid_registers_t *setfunc __attribute__ ((unused)), 71 void *arg __attribute__ ((unused))) 72 { 73 #ifndef __powerpc__ 74 return false; 75 #else /* __powerpc__ */ 76 union 77 { 78 struct pt_regs r; 79 long l[sizeof (struct pt_regs) / sizeof (long)]; 80 } 81 user_regs; 82 eu_static_assert (sizeof (struct pt_regs) % sizeof (long) == 0); 83 /* PTRACE_GETREGS is EIO on kernel-2.6.18-308.el5.ppc64. */ 84 errno = 0; 85 for (unsigned regno = 0; regno < sizeof (user_regs) / sizeof (long); 86 regno++) 87 { 88 user_regs.l[regno] = ptrace (PTRACE_PEEKUSER, tid, 89 (void *) (uintptr_t) (regno 90 * sizeof (long)), 91 NULL); 92 if (errno != 0) 93 return false; 94 } 95 const size_t gprs = sizeof (user_regs.r.gpr) / sizeof (*user_regs.r.gpr); 96 Dwarf_Word dwarf_regs[gprs]; 97 for (unsigned gpr = 0; gpr < gprs; gpr++) 98 dwarf_regs[gpr] = user_regs.r.gpr[gpr]; 99 if (! setfunc (0, gprs, dwarf_regs, arg)) 100 return false; 101 dwarf_regs[0] = user_regs.r.link; 102 // LR uses both 65 and 108 numbers, there is no consistency for it. 103 if (! setfunc (65, 1, dwarf_regs, arg)) 104 return false; 105 /* Registers like msr, ctr, xer, dar, dsisr etc. are probably irrelevant 106 for CFI. */ 107 dwarf_regs[0] = user_regs.r.nip; 108 return setfunc (-1, 1, dwarf_regs, arg); 109 #endif /* __powerpc__ */ 110 } 111 112 __typeof (ppc_set_initial_registers_tid) 113 ppc64_set_initial_registers_tid 114 __attribute__ ((alias ("ppc_set_initial_registers_tid"))); 115