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 <stdlib.h> 9 #include <sys/ptrace.h> 10 #ifdef __i386__ 11 #include <sys/user.h> 12 #endif 13 #include <longjmp.h> 14 #include <sysdep/ptrace_user.h> 15 #include <sys/uio.h> 16 #include <asm/sigcontext.h> 17 #include <linux/elf.h> 18 #include <registers.h> 19 #include <sys/mman.h> 20 21 unsigned long host_fp_size; 22 23 int get_fp_registers(int pid, unsigned long *regs) 24 { 25 struct iovec iov = { 26 .iov_base = regs, 27 .iov_len = host_fp_size, 28 }; 29 30 if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) < 0) 31 return -errno; 32 return 0; 33 } 34 35 int put_fp_registers(int pid, unsigned long *regs) 36 { 37 struct iovec iov = { 38 .iov_base = regs, 39 .iov_len = host_fp_size, 40 }; 41 42 if (ptrace(PTRACE_SETREGSET, pid, NT_X86_XSTATE, &iov) < 0) 43 return -errno; 44 return 0; 45 } 46 47 int arch_init_registers(int pid) 48 { 49 struct iovec iov = { 50 /* Just use plenty of space, it does not cost us anything */ 51 .iov_len = 2 * 1024 * 1024, 52 }; 53 int ret; 54 55 iov.iov_base = mmap(NULL, iov.iov_len, PROT_WRITE | PROT_READ, 56 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 57 if (iov.iov_base == MAP_FAILED) 58 return -ENOMEM; 59 60 /* GDB has x86_xsave_length, which uses x86_cpuid_count */ 61 ret = ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov); 62 if (ret) 63 ret = -errno; 64 munmap(iov.iov_base, 2 * 1024 * 1024); 65 66 host_fp_size = iov.iov_len; 67 68 return ret; 69 } 70 71 unsigned long get_thread_reg(int reg, jmp_buf *buf) 72 { 73 switch (reg) { 74 #ifdef __i386__ 75 case HOST_IP: 76 return buf[0]->__eip; 77 case HOST_SP: 78 return buf[0]->__esp; 79 case HOST_BP: 80 return buf[0]->__ebp; 81 #else 82 case HOST_IP: 83 return buf[0]->__rip; 84 case HOST_SP: 85 return buf[0]->__rsp; 86 case HOST_BP: 87 return buf[0]->__rbp; 88 #endif 89 default: 90 printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", 91 reg); 92 return 0; 93 } 94 } 95