registers.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. #include <errno.h>
  7. #include <sys/ptrace.h>
  8. #ifdef __i386__
  9. #include <sys/user.h>
  10. #endif
  11. #include <longjmp.h>
  12. #include <sysdep/ptrace_user.h>
  13. int save_fp_registers(int pid, unsigned long *fp_regs)
  14. {
  15. if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
  16. return -errno;
  17. return 0;
  18. }
  19. int restore_fp_registers(int pid, unsigned long *fp_regs)
  20. {
  21. if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0)
  22. return -errno;
  23. return 0;
  24. }
  25. #ifdef __i386__
  26. int have_fpx_regs = 1;
  27. int save_fpx_registers(int pid, unsigned long *fp_regs)
  28. {
  29. if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0)
  30. return -errno;
  31. return 0;
  32. }
  33. int restore_fpx_registers(int pid, unsigned long *fp_regs)
  34. {
  35. if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0)
  36. return -errno;
  37. return 0;
  38. }
  39. int get_fp_registers(int pid, unsigned long *regs)
  40. {
  41. if (have_fpx_regs)
  42. return save_fpx_registers(pid, regs);
  43. else
  44. return save_fp_registers(pid, regs);
  45. }
  46. int put_fp_registers(int pid, unsigned long *regs)
  47. {
  48. if (have_fpx_regs)
  49. return restore_fpx_registers(pid, regs);
  50. else
  51. return restore_fp_registers(pid, regs);
  52. }
  53. void arch_init_registers(int pid)
  54. {
  55. struct user_fpxregs_struct fpx_regs;
  56. int err;
  57. err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs);
  58. if (!err)
  59. return;
  60. if (errno != EIO)
  61. panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
  62. errno);
  63. have_fpx_regs = 0;
  64. }
  65. #else
  66. int get_fp_registers(int pid, unsigned long *regs)
  67. {
  68. return save_fp_registers(pid, regs);
  69. }
  70. int put_fp_registers(int pid, unsigned long *regs)
  71. {
  72. return restore_fp_registers(pid, regs);
  73. }
  74. #endif
  75. unsigned long get_thread_reg(int reg, jmp_buf *buf)
  76. {
  77. switch (reg) {
  78. #ifdef __i386__
  79. case HOST_IP:
  80. return buf[0]->__eip;
  81. case HOST_SP:
  82. return buf[0]->__esp;
  83. case HOST_BP:
  84. return buf[0]->__ebp;
  85. #else
  86. case HOST_IP:
  87. return buf[0]->__rip;
  88. case HOST_SP:
  89. return buf[0]->__rsp;
  90. case HOST_BP:
  91. return buf[0]->__rbp;
  92. #endif
  93. default:
  94. printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n",
  95. reg);
  96. return 0;
  97. }
  98. }