1 /* 2 * This file is part of ltrace. 3 * 4 * Copyright (C) 2013 Imagination Technologies Ltd. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * version 2 as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18 * 02110-1301 USA 19 */ 20 21 #include "config.h" 22 23 #include <sys/types.h> 24 #include <sys/ptrace.h> 25 #include <linux/uio.h> 26 #include <asm/ptrace.h> 27 28 #include "proc.h" 29 #include "common.h" 30 31 arch_addr_t 32 get_instruction_pointer(struct process *proc) 33 { 34 struct user_gp_regs regs; 35 struct iovec iov; 36 37 iov.iov_base = ®s; 38 iov.iov_len = sizeof(regs); 39 if (ptrace(PTRACE_GETREGSET, proc->pid, NT_PRSTATUS, (long)&iov)) 40 return (void *)-1; 41 42 return (void *)regs.pc; /* PC */ 43 } 44 45 void 46 set_instruction_pointer(struct process *proc, arch_addr_t addr) 47 { 48 struct user_gp_regs regs; 49 struct iovec iov; 50 51 iov.iov_base = ®s; 52 iov.iov_len = sizeof(regs); 53 if (ptrace(PTRACE_GETREGSET, proc->pid, NT_PRSTATUS, (long)&iov)) 54 return; 55 56 regs.pc = (unsigned long)addr; 57 58 iov.iov_base = ®s; 59 iov.iov_len = sizeof(regs); 60 ptrace(PTRACE_SETREGSET, proc->pid, NT_PRSTATUS, (long)&iov); 61 } 62 63 arch_addr_t 64 get_stack_pointer(struct process *proc) 65 { 66 struct user_gp_regs regs; 67 struct iovec iov; 68 69 iov.iov_base = ®s; 70 iov.iov_len = sizeof(regs); 71 if (ptrace(PTRACE_GETREGSET, proc->pid, NT_PRSTATUS, (long)&iov)) 72 return (void *)-1; 73 74 return (void *)regs.ax[0][0]; /* A0StP (A0.0) */ 75 } 76 77 arch_addr_t 78 get_return_addr(struct process *proc, void *stack_pointer) 79 { 80 struct user_gp_regs regs; 81 struct iovec iov; 82 83 iov.iov_base = ®s; 84 iov.iov_len = sizeof(regs); 85 if (ptrace(PTRACE_GETREGSET, proc->pid, NT_PRSTATUS, (long)&iov)) 86 return (void *)-1; 87 88 return (void *)regs.dx[4][1]; /* D1RtP (D1.4) */ 89 } 90