regs.c revision f13505251e6402460f6cc7ec84e0d8ca91607b4f
15570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand#if HAVE_CONFIG_H
25570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand#include "config.h"
35570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand#endif
45570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand
55570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand#include <sys/types.h>
65570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand#include <sys/ptrace.h>
75570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand
82d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand#include <asm/ptrace_offsets.h>
92d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand#include <asm/rse.h>
105570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand
115570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand#include <stddef.h>
125570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand#include "debug.h"
135570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand#include "ltrace.h"
145570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand
15f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid *
16f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesget_instruction_pointer(struct process *proc) {
175570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand	unsigned long ip = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IIP, 0);
182d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	unsigned long slot =
192d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	    (ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0) >> 41) & 3;
202d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand
212d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	return (void *)(ip | slot);
225570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand}
235570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand
24f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid
25f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesset_instruction_pointer(struct process *proc, void *addr) {
265570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand
275570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand	unsigned long newip = (unsigned long)addr;
28a841f6592e75d78620ee9e645af22a58c9e3bbf9Olaf Hering	unsigned long slot = (unsigned long)addr & 0xf;
295570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand	unsigned long psr = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0);
302d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand
315570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand	psr &= ~(3UL << 41);
32a841f6592e75d78620ee9e645af22a58c9e3bbf9Olaf Hering	psr |= (slot & 0x3) << 41;
332d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand
345570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand	newip &= ~0xfUL;
355570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand
365570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand	ptrace(PTRACE_POKEUSER, proc->pid, PT_CR_IIP, (long)newip);
375570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand	ptrace(PTRACE_POKEUSER, proc->pid, PT_CR_IPSR, psr);
385570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand}
395570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand
40f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid *
41f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesget_stack_pointer(struct process *proc) {
425570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, PT_R12, 0);
435570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand}
445570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand
45f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid *
46f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesget_return_addr(struct process *proc, void *stack_pointer) {
475570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, PT_B0, 0);
485570a7769869a4df25ef85f302f74a7feb6c0cd3Ian Wienand}
49