registers.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * Copyright (C) 2004 PathScale, Inc
  3. * Licensed under the GPL
  4. */
  5. #include <errno.h>
  6. #include <string.h>
  7. #include "sysdep/ptrace_user.h"
  8. #include "sysdep/ptrace.h"
  9. #include "uml-config.h"
  10. #include "skas_ptregs.h"
  11. #include "registers.h"
  12. #include "user.h"
  13. /* These are set once at boot time and not changed thereafter */
  14. static unsigned long exec_regs[HOST_FRAME_SIZE];
  15. static unsigned long exec_fp_regs[HOST_FP_SIZE];
  16. static unsigned long exec_fpx_regs[HOST_XFP_SIZE];
  17. static int have_fpx_regs = 1;
  18. void init_thread_registers(union uml_pt_regs *to)
  19. {
  20. memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs));
  21. memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp));
  22. if(have_fpx_regs)
  23. memcpy(to->skas.xfp, exec_fpx_regs, sizeof(to->skas.xfp));
  24. }
  25. /* XXX These need to use [GS]ETFPXREGS and copy_sc_{to,from}_user_skas needs
  26. * to pass in a sufficiently large buffer
  27. */
  28. int save_fp_registers(int pid, unsigned long *fp_regs)
  29. {
  30. if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
  31. return(-errno);
  32. return(0);
  33. }
  34. int restore_fp_registers(int pid, unsigned long *fp_regs)
  35. {
  36. if(ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0)
  37. return(-errno);
  38. return(0);
  39. }
  40. static int move_registers(int pid, int int_op, union uml_pt_regs *regs,
  41. int fp_op, unsigned long *fp_regs)
  42. {
  43. if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
  44. return(-errno);
  45. if(ptrace(fp_op, pid, 0, fp_regs) < 0)
  46. return(-errno);
  47. return(0);
  48. }
  49. void save_registers(int pid, union uml_pt_regs *regs)
  50. {
  51. unsigned long *fp_regs;
  52. int err, fp_op;
  53. if(have_fpx_regs){
  54. fp_op = PTRACE_GETFPXREGS;
  55. fp_regs = regs->skas.xfp;
  56. }
  57. else {
  58. fp_op = PTRACE_GETFPREGS;
  59. fp_regs = regs->skas.fp;
  60. }
  61. err = move_registers(pid, PTRACE_GETREGS, regs, fp_op, fp_regs);
  62. if(err)
  63. panic("save_registers - saving registers failed, errno = %d\n",
  64. -err);
  65. }
  66. void restore_registers(int pid, union uml_pt_regs *regs)
  67. {
  68. unsigned long *fp_regs;
  69. int err, fp_op;
  70. if(have_fpx_regs){
  71. fp_op = PTRACE_SETFPXREGS;
  72. fp_regs = regs->skas.xfp;
  73. }
  74. else {
  75. fp_op = PTRACE_SETFPREGS;
  76. fp_regs = regs->skas.fp;
  77. }
  78. err = move_registers(pid, PTRACE_SETREGS, regs, fp_op, fp_regs);
  79. if(err)
  80. panic("restore_registers - saving registers failed, "
  81. "errno = %d\n", -err);
  82. }
  83. void init_registers(int pid)
  84. {
  85. int err;
  86. err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
  87. if(err)
  88. panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
  89. err);
  90. errno = 0;
  91. err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
  92. if(!err)
  93. return;
  94. if(errno != EIO)
  95. panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
  96. errno);
  97. have_fpx_regs = 0;
  98. err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
  99. if(err)
  100. panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
  101. err);
  102. }
  103. /*
  104. * Overrides for Emacs so that we follow Linus's tabbing style.
  105. * Emacs will notice this stuff at the end of the file and automatically
  106. * adjust the settings for this buffer only. This must remain at the end
  107. * of the file.
  108. * ---------------------------------------------------------------------------
  109. * Local variables:
  110. * c-file-style: "linux"
  111. * End:
  112. */