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