ptrace_user.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
  3. * Licensed under the GPL
  4. */
  5. #include <stdio.h>
  6. #include <stddef.h>
  7. #include <errno.h>
  8. #include <unistd.h>
  9. #include "ptrace_user.h"
  10. /* Grr, asm/user.h includes asm/ptrace.h, so has to follow ptrace_user.h */
  11. #include <asm/user.h>
  12. #include "kern_util.h"
  13. #include "sysdep/thread.h"
  14. #include "user.h"
  15. #include "os.h"
  16. #include "uml-config.h"
  17. #include "user_util.h"
  18. int ptrace_getregs(long pid, unsigned long *regs_out)
  19. {
  20. if (ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0)
  21. return -errno;
  22. return 0;
  23. }
  24. int ptrace_setregs(long pid, unsigned long *regs)
  25. {
  26. if (ptrace(PTRACE_SETREGS, pid, 0, regs) < 0)
  27. return -errno;
  28. return 0;
  29. }
  30. int ptrace_getfpregs(long pid, unsigned long *regs)
  31. {
  32. if (ptrace(PTRACE_GETFPREGS, pid, 0, regs) < 0)
  33. return -errno;
  34. return 0;
  35. }
  36. int ptrace_setfpregs(long pid, unsigned long *regs)
  37. {
  38. if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0)
  39. return -errno;
  40. return 0;
  41. }
  42. /* All the below stuff is of interest for TT mode only */
  43. static void write_debugregs(int pid, unsigned long *regs)
  44. {
  45. struct user *dummy;
  46. int nregs, i;
  47. dummy = NULL;
  48. nregs = ARRAY_SIZE(dummy->u_debugreg);
  49. for(i = 0; i < nregs; i++){
  50. if((i == 4) || (i == 5)) continue;
  51. if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
  52. regs[i]) < 0)
  53. printk("write_debugregs - ptrace failed on "
  54. "register %d, value = 0x%lx, errno = %d\n", i,
  55. regs[i], errno);
  56. }
  57. }
  58. static void read_debugregs(int pid, unsigned long *regs)
  59. {
  60. struct user *dummy;
  61. int nregs, i;
  62. dummy = NULL;
  63. nregs = ARRAY_SIZE(dummy->u_debugreg);
  64. for(i = 0; i < nregs; i++){
  65. regs[i] = ptrace(PTRACE_PEEKUSR, pid,
  66. &dummy->u_debugreg[i], 0);
  67. }
  68. }
  69. /* Accessed only by the tracing thread */
  70. static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
  71. void arch_enter_kernel(void *task, int pid)
  72. {
  73. read_debugregs(pid, TASK_DEBUGREGS(task));
  74. write_debugregs(pid, kernel_debugregs);
  75. }
  76. void arch_leave_kernel(void *task, int pid)
  77. {
  78. read_debugregs(pid, kernel_debugregs);
  79. write_debugregs(pid, TASK_DEBUGREGS(task));
  80. }
  81. #ifdef UML_CONFIG_PT_PROXY
  82. /* Accessed only by the tracing thread */
  83. static int debugregs_seq;
  84. /* Only called by the ptrace proxy */
  85. void ptrace_pokeuser(unsigned long addr, unsigned long data)
  86. {
  87. if((addr < offsetof(struct user, u_debugreg[0])) ||
  88. (addr > offsetof(struct user, u_debugreg[7])))
  89. return;
  90. addr -= offsetof(struct user, u_debugreg[0]);
  91. addr = addr >> 2;
  92. if(kernel_debugregs[addr] == data) return;
  93. kernel_debugregs[addr] = data;
  94. debugregs_seq++;
  95. }
  96. static void update_debugregs_cb(void *arg)
  97. {
  98. int pid = *((int *) arg);
  99. write_debugregs(pid, kernel_debugregs);
  100. }
  101. /* Optimized out in its header when not defined */
  102. void update_debugregs(int seq)
  103. {
  104. int me;
  105. if(seq == debugregs_seq) return;
  106. me = os_getpid();
  107. initial_thread_cb(update_debugregs_cb, &me);
  108. }
  109. #endif
  110. /*
  111. * Overrides for Emacs so that we follow Linus's tabbing style.
  112. * Emacs will notice this stuff at the end of the file and automatically
  113. * adjust the settings for this buffer only. This must remain at the end
  114. * of the file.
  115. * ---------------------------------------------------------------------------
  116. * Local variables:
  117. * c-file-style: "linux"
  118. * End:
  119. */