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