1 /* 2 * This file is part of ltrace. 3 * Copyright (C) 2013 Petr Machata, Red Hat Inc. 4 * Copyright (C) 2002,2004,2008,2009 Juan Cespedes 5 * Copyright (C) 2009 Juan Cespedes 6 * Copyright (C) 2006 Ian Wienand 7 * Copyright (C) 2001 IBM Poughkeepsie, IBM Corporation 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of the 12 * License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 22 * 02110-1301 USA 23 */ 24 25 #include "config.h" 26 27 #include <sys/types.h> 28 #include <sys/ptrace.h> 29 #include <asm/ptrace.h> 30 31 #include "proc.h" 32 #include "common.h" 33 34 #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) 35 # define PTRACE_PEEKUSER PTRACE_PEEKUSR 36 #endif 37 38 #if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) 39 # define PTRACE_POKEUSER PTRACE_POKEUSR 40 #endif 41 42 #ifdef __s390x__ 43 #define PSW_MASK 0xffffffffffffffff 44 #define PSW_MASK31 0x7fffffff 45 #else 46 #define PSW_MASK 0x7fffffff 47 #endif 48 49 arch_addr_t 50 get_instruction_pointer(struct process *proc) 51 { 52 long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWADDR, 0) & PSW_MASK; 53 #ifdef __s390x__ 54 if (proc->mask_32bit) 55 ret &= PSW_MASK31; 56 #endif 57 /* XXX double cast. */ 58 return (arch_addr_t)ret; 59 } 60 61 void 62 set_instruction_pointer(struct process *proc, arch_addr_t addr) 63 { 64 #ifdef __s390x__ 65 if (proc->mask_32bit) 66 /* XXX double cast. */ 67 addr = (arch_addr_t)((uintptr_t)addr & PSW_MASK31); 68 #else 69 /* XXX double cast. */ 70 addr = (arch_addr_t)((uintptr_t)addr | ~PSW_MASK); 71 #endif 72 ptrace(PTRACE_POKEUSER, proc->pid, PT_PSWADDR, addr); 73 } 74 75 arch_addr_t 76 get_stack_pointer(struct process *proc) 77 { 78 long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR15, 0) & PSW_MASK; 79 #ifdef __s390x__ 80 if (proc->mask_32bit) 81 ret &= PSW_MASK31; 82 #endif 83 /* XXX double cast. */ 84 return (arch_addr_t)ret; 85 } 86 87 arch_addr_t 88 get_return_addr(struct process *proc, arch_addr_t stack_pointer) 89 { 90 long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR14, 0) & PSW_MASK; 91 #ifdef __s390x__ 92 if (proc->mask_32bit) 93 ret &= PSW_MASK31; 94 #endif 95 /* XXX double cast. */ 96 return (arch_addr_t)ret; 97 } 98