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")));