1/* 2 * Copyright (C) 2004 PathScale, Inc 3 * Licensed under the GPL 4 */ 5 6#include <errno.h> 7#include <string.h> 8#include "ptrace_user.h" 9#include "uml-config.h" 10#include "skas_ptregs.h" 11#include "registers.h" 12#include "longjmp.h" 13#include "user.h" 14 15/* These are set once at boot time and not changed thereafter */ 16 17static unsigned long exec_regs[MAX_REG_NR]; 18static unsigned long exec_fp_regs[HOST_FP_SIZE]; 19 20void init_thread_registers(union uml_pt_regs *to) 21{ 22 memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs)); 23 memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp)); 24} 25 26static int move_registers(int pid, int int_op, int fp_op, 27 union uml_pt_regs *regs) 28{ 29 if(ptrace(int_op, pid, 0, regs->skas.regs) < 0) 30 return -errno; 31 32 if(ptrace(fp_op, pid, 0, regs->skas.fp) < 0) 33 return -errno; 34 35 return 0; 36} 37 38void save_registers(int pid, union uml_pt_regs *regs) 39{ 40 int err; 41 42 err = move_registers(pid, PTRACE_GETREGS, PTRACE_GETFPREGS, regs); 43 if(err) 44 panic("save_registers - saving registers failed, errno = %d\n", 45 -err); 46} 47 48void restore_registers(int pid, union uml_pt_regs *regs) 49{ 50 int err; 51 52 err = move_registers(pid, PTRACE_SETREGS, PTRACE_SETFPREGS, regs); 53 if(err) 54 panic("restore_registers - saving registers failed, " 55 "errno = %d\n", -err); 56} 57 58void init_registers(int pid) 59{ 60 int err; 61 62 err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); 63 if(err) 64 panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", 65 errno); 66 67 err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); 68 if(err) 69 panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", 70 errno); 71} 72 73void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) 74{ 75 memcpy(regs, exec_regs, sizeof(exec_regs)); 76 if(fp_regs != NULL) 77 memcpy(fp_regs, exec_fp_regs, 78 HOST_FP_SIZE * sizeof(unsigned long)); 79} 80 81unsigned long get_thread_reg(int reg, jmp_buf *buf) 82{ 83 switch(reg){ 84 case RIP: return buf[0]->__rip; 85 case RSP: return buf[0]->__rsp; 86 case RBP: return buf[0]->__rbp; 87 default: 88 printk("get_thread_regs - unknown register %d\n", reg); 89 return 0; 90 } 91} 92