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