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
get_instruction_pointer(struct process * proc)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
set_instruction_pointer(struct process * proc,arch_addr_t addr)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
get_stack_pointer(struct process * proc)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
get_return_addr(struct process * proc,arch_addr_t stack_pointer)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