ptrace.cpp 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. /*
  2. * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <errno.h>
  7. #include <sys/ptrace.h>
  8. #include <syscall.h>
  9. extern "C" {
  10. long ptrace(int request, pid_t tid, void* addr, void* data)
  11. {
  12. if (request == PT_PEEKBUF) {
  13. // PT_PEEKBUF cannot easily be correctly used through this function signature:
  14. // The amount of data to be copied is not available.
  15. // We could VERIFY() here, but to safeguard against ports that attempt to use
  16. // the same number, let's claim that the Kernel just doesn't know the command.
  17. // Use Core::System::ptrace_peekbuf instead.
  18. return EINVAL;
  19. }
  20. // PT_PEEK needs special handling since the syscall wrapper
  21. // returns the peeked value as an int, which can be negative because of the cast.
  22. // When using PT_PEEK, the user can check if an error occurred
  23. // by looking at errno rather than the return value.
  24. FlatPtr out_data;
  25. auto is_peek_type = request == PT_PEEK || request == PT_PEEKDEBUG;
  26. if (is_peek_type) {
  27. data = &out_data;
  28. }
  29. Syscall::SC_ptrace_params params {
  30. request,
  31. tid,
  32. addr,
  33. (FlatPtr)data
  34. };
  35. long rc = syscall(SC_ptrace, &params);
  36. if (is_peek_type) {
  37. if (rc < 0) {
  38. errno = -rc;
  39. return -1;
  40. }
  41. errno = 0;
  42. return static_cast<long>(out_data);
  43. }
  44. __RETURN_WITH_ERRNO(rc, rc, -1);
  45. }
  46. }