RegsArm64.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright (C) 2016 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <stdint.h>
  17. #include <string.h>
  18. #include <functional>
  19. #include <unwindstack/Elf.h>
  20. #include <unwindstack/MachineArm64.h>
  21. #include <unwindstack/MapInfo.h>
  22. #include <unwindstack/Memory.h>
  23. #include <unwindstack/RegsArm64.h>
  24. #include <unwindstack/UcontextArm64.h>
  25. #include <unwindstack/UserArm64.h>
  26. namespace unwindstack {
  27. RegsArm64::RegsArm64()
  28. : RegsImpl<uint64_t>(ARM64_REG_LAST, Location(LOCATION_REGISTER, ARM64_REG_LR)) {}
  29. ArchEnum RegsArm64::Arch() {
  30. return ARCH_ARM64;
  31. }
  32. uint64_t RegsArm64::pc() {
  33. return regs_[ARM64_REG_PC];
  34. }
  35. uint64_t RegsArm64::sp() {
  36. return regs_[ARM64_REG_SP];
  37. }
  38. void RegsArm64::set_pc(uint64_t pc) {
  39. regs_[ARM64_REG_PC] = pc;
  40. }
  41. void RegsArm64::set_sp(uint64_t sp) {
  42. regs_[ARM64_REG_SP] = sp;
  43. }
  44. uint64_t RegsArm64::GetPcAdjustment(uint64_t rel_pc, Elf*) {
  45. if (rel_pc < 4) {
  46. return 0;
  47. }
  48. return 4;
  49. }
  50. bool RegsArm64::SetPcFromReturnAddress(Memory*) {
  51. uint64_t lr = regs_[ARM64_REG_LR];
  52. if (regs_[ARM64_REG_PC] == lr) {
  53. return false;
  54. }
  55. regs_[ARM64_REG_PC] = lr;
  56. return true;
  57. }
  58. void RegsArm64::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
  59. fn("x0", regs_[ARM64_REG_R0]);
  60. fn("x1", regs_[ARM64_REG_R1]);
  61. fn("x2", regs_[ARM64_REG_R2]);
  62. fn("x3", regs_[ARM64_REG_R3]);
  63. fn("x4", regs_[ARM64_REG_R4]);
  64. fn("x5", regs_[ARM64_REG_R5]);
  65. fn("x6", regs_[ARM64_REG_R6]);
  66. fn("x7", regs_[ARM64_REG_R7]);
  67. fn("x8", regs_[ARM64_REG_R8]);
  68. fn("x9", regs_[ARM64_REG_R9]);
  69. fn("x10", regs_[ARM64_REG_R10]);
  70. fn("x11", regs_[ARM64_REG_R11]);
  71. fn("x12", regs_[ARM64_REG_R12]);
  72. fn("x13", regs_[ARM64_REG_R13]);
  73. fn("x14", regs_[ARM64_REG_R14]);
  74. fn("x15", regs_[ARM64_REG_R15]);
  75. fn("x16", regs_[ARM64_REG_R16]);
  76. fn("x17", regs_[ARM64_REG_R17]);
  77. fn("x18", regs_[ARM64_REG_R18]);
  78. fn("x19", regs_[ARM64_REG_R19]);
  79. fn("x20", regs_[ARM64_REG_R20]);
  80. fn("x21", regs_[ARM64_REG_R21]);
  81. fn("x22", regs_[ARM64_REG_R22]);
  82. fn("x23", regs_[ARM64_REG_R23]);
  83. fn("x24", regs_[ARM64_REG_R24]);
  84. fn("x25", regs_[ARM64_REG_R25]);
  85. fn("x26", regs_[ARM64_REG_R26]);
  86. fn("x27", regs_[ARM64_REG_R27]);
  87. fn("x28", regs_[ARM64_REG_R28]);
  88. fn("x29", regs_[ARM64_REG_R29]);
  89. fn("sp", regs_[ARM64_REG_SP]);
  90. fn("lr", regs_[ARM64_REG_LR]);
  91. fn("pc", regs_[ARM64_REG_PC]);
  92. }
  93. Regs* RegsArm64::Read(void* remote_data) {
  94. arm64_user_regs* user = reinterpret_cast<arm64_user_regs*>(remote_data);
  95. RegsArm64* regs = new RegsArm64();
  96. memcpy(regs->RawData(), &user->regs[0], (ARM64_REG_R31 + 1) * sizeof(uint64_t));
  97. uint64_t* reg_data = reinterpret_cast<uint64_t*>(regs->RawData());
  98. reg_data[ARM64_REG_PC] = user->pc;
  99. reg_data[ARM64_REG_SP] = user->sp;
  100. return regs;
  101. }
  102. Regs* RegsArm64::CreateFromUcontext(void* ucontext) {
  103. arm64_ucontext_t* arm64_ucontext = reinterpret_cast<arm64_ucontext_t*>(ucontext);
  104. RegsArm64* regs = new RegsArm64();
  105. memcpy(regs->RawData(), &arm64_ucontext->uc_mcontext.regs[0], ARM64_REG_LAST * sizeof(uint64_t));
  106. return regs;
  107. }
  108. bool RegsArm64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
  109. uint64_t data;
  110. Memory* elf_memory = elf->memory();
  111. // Read from elf memory since it is usually more expensive to read from
  112. // process memory.
  113. if (!elf_memory->ReadFully(rel_pc, &data, sizeof(data))) {
  114. return false;
  115. }
  116. // Look for the kernel sigreturn function.
  117. // __kernel_rt_sigreturn:
  118. // 0xd2801168 mov x8, #0x8b
  119. // 0xd4000001 svc #0x0
  120. if (data != 0xd4000001d2801168ULL) {
  121. return false;
  122. }
  123. // SP + sizeof(siginfo_t) + uc_mcontext offset + X0 offset.
  124. if (!process_memory->ReadFully(regs_[ARM64_REG_SP] + 0x80 + 0xb0 + 0x08, regs_.data(),
  125. sizeof(uint64_t) * ARM64_REG_LAST)) {
  126. return false;
  127. }
  128. return true;
  129. }
  130. Regs* RegsArm64::Clone() {
  131. return new RegsArm64(*this);
  132. }
  133. } // namespace unwindstack