xref: /linux/arch/x86/um/os-Linux/registers.c (revision 38b64aed786d59854ecc850ee5ece85b61dd252b)
15c48b108SAl Viro /*
25c48b108SAl Viro  * Copyright (C) 2004 PathScale, Inc
35c48b108SAl Viro  * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
45c48b108SAl Viro  * Licensed under the GPL
55c48b108SAl Viro  */
65c48b108SAl Viro 
75c48b108SAl Viro #include <errno.h>
85c48b108SAl Viro #include <sys/ptrace.h>
9*38b64aedSRichard Weinberger #ifdef __i386__
105c48b108SAl Viro #include <sys/user.h>
11*38b64aedSRichard Weinberger #endif
125c48b108SAl Viro #include "longjmp.h"
135c48b108SAl Viro #include "sysdep/ptrace_user.h"
145c48b108SAl Viro 
155c48b108SAl Viro int save_fp_registers(int pid, unsigned long *fp_regs)
165c48b108SAl Viro {
175c48b108SAl Viro 	if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
185c48b108SAl Viro 		return -errno;
195c48b108SAl Viro 	return 0;
205c48b108SAl Viro }
215c48b108SAl Viro 
225c48b108SAl Viro int restore_fp_registers(int pid, unsigned long *fp_regs)
235c48b108SAl Viro {
245c48b108SAl Viro 	if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0)
255c48b108SAl Viro 		return -errno;
265c48b108SAl Viro 	return 0;
275c48b108SAl Viro }
285c48b108SAl Viro 
295c48b108SAl Viro #ifdef __i386__
305c48b108SAl Viro int have_fpx_regs = 1;
315c48b108SAl Viro int save_fpx_registers(int pid, unsigned long *fp_regs)
325c48b108SAl Viro {
335c48b108SAl Viro 	if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0)
345c48b108SAl Viro 		return -errno;
355c48b108SAl Viro 	return 0;
365c48b108SAl Viro }
375c48b108SAl Viro 
385c48b108SAl Viro int restore_fpx_registers(int pid, unsigned long *fp_regs)
395c48b108SAl Viro {
405c48b108SAl Viro 	if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0)
415c48b108SAl Viro 		return -errno;
425c48b108SAl Viro 	return 0;
435c48b108SAl Viro }
445c48b108SAl Viro 
455c48b108SAl Viro int get_fp_registers(int pid, unsigned long *regs)
465c48b108SAl Viro {
475c48b108SAl Viro 	if (have_fpx_regs)
485c48b108SAl Viro 		return save_fpx_registers(pid, regs);
495c48b108SAl Viro 	else
505c48b108SAl Viro 		return save_fp_registers(pid, regs);
515c48b108SAl Viro }
525c48b108SAl Viro 
535c48b108SAl Viro int put_fp_registers(int pid, unsigned long *regs)
545c48b108SAl Viro {
555c48b108SAl Viro 	if (have_fpx_regs)
565c48b108SAl Viro 		return restore_fpx_registers(pid, regs);
575c48b108SAl Viro 	else
585c48b108SAl Viro 		return restore_fp_registers(pid, regs);
595c48b108SAl Viro }
605c48b108SAl Viro 
615c48b108SAl Viro void arch_init_registers(int pid)
625c48b108SAl Viro {
635c48b108SAl Viro 	struct user_fpxregs_struct fpx_regs;
645c48b108SAl Viro 	int err;
655c48b108SAl Viro 
665c48b108SAl Viro 	err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs);
675c48b108SAl Viro 	if (!err)
685c48b108SAl Viro 		return;
695c48b108SAl Viro 
705c48b108SAl Viro 	if (errno != EIO)
715c48b108SAl Viro 		panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
725c48b108SAl Viro 		      errno);
735c48b108SAl Viro 
745c48b108SAl Viro 	have_fpx_regs = 0;
755c48b108SAl Viro }
765c48b108SAl Viro #else
775c48b108SAl Viro 
785c48b108SAl Viro int get_fp_registers(int pid, unsigned long *regs)
795c48b108SAl Viro {
805c48b108SAl Viro 	return save_fp_registers(pid, regs);
815c48b108SAl Viro }
825c48b108SAl Viro 
835c48b108SAl Viro int put_fp_registers(int pid, unsigned long *regs)
845c48b108SAl Viro {
855c48b108SAl Viro 	return restore_fp_registers(pid, regs);
865c48b108SAl Viro }
875c48b108SAl Viro 
885c48b108SAl Viro #endif
895c48b108SAl Viro 
905c48b108SAl Viro unsigned long get_thread_reg(int reg, jmp_buf *buf)
915c48b108SAl Viro {
925c48b108SAl Viro 	switch (reg) {
935c48b108SAl Viro #ifdef __i386__
94a10c95d8SAl Viro 	case HOST_IP:
955c48b108SAl Viro 		return buf[0]->__eip;
96a10c95d8SAl Viro 	case HOST_SP:
975c48b108SAl Viro 		return buf[0]->__esp;
98a10c95d8SAl Viro 	case HOST_BP:
995c48b108SAl Viro 		return buf[0]->__ebp;
1005c48b108SAl Viro #else
101a10c95d8SAl Viro 	case HOST_IP:
1025c48b108SAl Viro 		return buf[0]->__rip;
103a10c95d8SAl Viro 	case HOST_SP:
1045c48b108SAl Viro 		return buf[0]->__rsp;
105a10c95d8SAl Viro 	case HOST_BP:
1065c48b108SAl Viro 		return buf[0]->__rbp;
1075c48b108SAl Viro #endif
1085c48b108SAl Viro 	default:
1095c48b108SAl Viro 		printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n",
1105c48b108SAl Viro 		       reg);
1115c48b108SAl Viro 		return 0;
1125c48b108SAl Viro 	}
1135c48b108SAl Viro }
114