Home | History | Annotate | Download | only in s390
      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