1 /* 2 * Copyright (C) 2004 PathScale, Inc 3 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 4 * Licensed under the GPL 5 */ 6 7 #include <errno.h> 8 #include <sys/ptrace.h> 9 #ifdef __i386__ 10 #include <sys/user.h> 11 #endif 12 #include "longjmp.h" 13 #include "sysdep/ptrace_user.h" 14 15 int save_fp_registers(int pid, unsigned long *fp_regs) 16 { 17 if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) 18 return -errno; 19 return 0; 20 } 21 22 int restore_fp_registers(int pid, unsigned long *fp_regs) 23 { 24 if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) 25 return -errno; 26 return 0; 27 } 28 29 #ifdef __i386__ 30 int have_fpx_regs = 1; 31 int save_fpx_registers(int pid, unsigned long *fp_regs) 32 { 33 if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0) 34 return -errno; 35 return 0; 36 } 37 38 int restore_fpx_registers(int pid, unsigned long *fp_regs) 39 { 40 if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0) 41 return -errno; 42 return 0; 43 } 44 45 int get_fp_registers(int pid, unsigned long *regs) 46 { 47 if (have_fpx_regs) 48 return save_fpx_registers(pid, regs); 49 else 50 return save_fp_registers(pid, regs); 51 } 52 53 int put_fp_registers(int pid, unsigned long *regs) 54 { 55 if (have_fpx_regs) 56 return restore_fpx_registers(pid, regs); 57 else 58 return restore_fp_registers(pid, regs); 59 } 60 61 void arch_init_registers(int pid) 62 { 63 struct user_fpxregs_struct fpx_regs; 64 int err; 65 66 err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs); 67 if (!err) 68 return; 69 70 if (errno != EIO) 71 panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", 72 errno); 73 74 have_fpx_regs = 0; 75 } 76 #else 77 78 int get_fp_registers(int pid, unsigned long *regs) 79 { 80 return save_fp_registers(pid, regs); 81 } 82 83 int put_fp_registers(int pid, unsigned long *regs) 84 { 85 return restore_fp_registers(pid, regs); 86 } 87 88 #endif 89 90 unsigned long get_thread_reg(int reg, jmp_buf *buf) 91 { 92 switch (reg) { 93 #ifdef __i386__ 94 case HOST_IP: 95 return buf[0]->__eip; 96 case HOST_SP: 97 return buf[0]->__esp; 98 case HOST_BP: 99 return buf[0]->__ebp; 100 #else 101 case HOST_IP: 102 return buf[0]->__rip; 103 case HOST_SP: 104 return buf[0]->__rsp; 105 case HOST_BP: 106 return buf[0]->__rbp; 107 #endif 108 default: 109 printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", 110 reg); 111 return 0; 112 } 113 } 114