ptrace.cpp 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  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. int ptrace(int request, pid_t tid, void* addr, int data)
  11. {
  12. // PT_PEEK needs special handling since the syscall wrapper
  13. // returns the peeked value as an int, which can be negative because of the cast.
  14. // When using PT_PEEK, the user can check if an error occurred
  15. // by looking at errno rather than the return value.
  16. u32 out_data;
  17. Syscall::SC_ptrace_peek_params peek_params;
  18. auto is_peek_type = request == PT_PEEK || request == PT_PEEKDEBUG;
  19. if (is_peek_type) {
  20. peek_params.address = reinterpret_cast<u32*>(addr);
  21. peek_params.out_data = &out_data;
  22. addr = &peek_params;
  23. }
  24. Syscall::SC_ptrace_params params {
  25. request,
  26. tid,
  27. reinterpret_cast<u8*>(addr),
  28. data
  29. };
  30. int rc = syscall(SC_ptrace, &params);
  31. if (is_peek_type) {
  32. if (rc < 0) {
  33. errno = -rc;
  34. return -1;
  35. }
  36. errno = 0;
  37. return static_cast<int>(out_data);
  38. }
  39. __RETURN_WITH_ERRNO(rc, rc, -1);
  40. }
  41. }