xref: /linux/arch/x86/um/os-Linux/registers.c (revision 5c48b108ecbf6505d929e64d50dace13ac2bdf34)
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