RegsX86.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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 <functional>
  18. #include <unwindstack/Elf.h>
  19. #include <unwindstack/MachineX86.h>
  20. #include <unwindstack/MapInfo.h>
  21. #include <unwindstack/Memory.h>
  22. #include <unwindstack/RegsX86.h>
  23. #include <unwindstack/UcontextX86.h>
  24. #include <unwindstack/UserX86.h>
  25. namespace unwindstack {
  26. RegsX86::RegsX86() : RegsImpl<uint32_t>(X86_REG_LAST, Location(LOCATION_SP_OFFSET, -4)) {}
  27. ArchEnum RegsX86::Arch() {
  28. return ARCH_X86;
  29. }
  30. uint64_t RegsX86::pc() {
  31. return regs_[X86_REG_PC];
  32. }
  33. uint64_t RegsX86::sp() {
  34. return regs_[X86_REG_SP];
  35. }
  36. void RegsX86::set_pc(uint64_t pc) {
  37. regs_[X86_REG_PC] = static_cast<uint32_t>(pc);
  38. }
  39. void RegsX86::set_sp(uint64_t sp) {
  40. regs_[X86_REG_SP] = static_cast<uint32_t>(sp);
  41. }
  42. uint64_t RegsX86::GetPcAdjustment(uint64_t rel_pc, Elf*) {
  43. if (rel_pc == 0) {
  44. return 0;
  45. }
  46. return 1;
  47. }
  48. bool RegsX86::SetPcFromReturnAddress(Memory* process_memory) {
  49. // Attempt to get the return address from the top of the stack.
  50. uint32_t new_pc;
  51. if (!process_memory->ReadFully(regs_[X86_REG_SP], &new_pc, sizeof(new_pc)) ||
  52. new_pc == regs_[X86_REG_PC]) {
  53. return false;
  54. }
  55. regs_[X86_REG_PC] = new_pc;
  56. return true;
  57. }
  58. void RegsX86::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
  59. fn("eax", regs_[X86_REG_EAX]);
  60. fn("ebx", regs_[X86_REG_EBX]);
  61. fn("ecx", regs_[X86_REG_ECX]);
  62. fn("edx", regs_[X86_REG_EDX]);
  63. fn("ebp", regs_[X86_REG_EBP]);
  64. fn("edi", regs_[X86_REG_EDI]);
  65. fn("esi", regs_[X86_REG_ESI]);
  66. fn("esp", regs_[X86_REG_ESP]);
  67. fn("eip", regs_[X86_REG_EIP]);
  68. }
  69. Regs* RegsX86::Read(void* user_data) {
  70. x86_user_regs* user = reinterpret_cast<x86_user_regs*>(user_data);
  71. RegsX86* regs = new RegsX86();
  72. (*regs)[X86_REG_EAX] = user->eax;
  73. (*regs)[X86_REG_EBX] = user->ebx;
  74. (*regs)[X86_REG_ECX] = user->ecx;
  75. (*regs)[X86_REG_EDX] = user->edx;
  76. (*regs)[X86_REG_EBP] = user->ebp;
  77. (*regs)[X86_REG_EDI] = user->edi;
  78. (*regs)[X86_REG_ESI] = user->esi;
  79. (*regs)[X86_REG_ESP] = user->esp;
  80. (*regs)[X86_REG_EIP] = user->eip;
  81. return regs;
  82. }
  83. void RegsX86::SetFromUcontext(x86_ucontext_t* ucontext) {
  84. // Put the registers in the expected order.
  85. regs_[X86_REG_EDI] = ucontext->uc_mcontext.edi;
  86. regs_[X86_REG_ESI] = ucontext->uc_mcontext.esi;
  87. regs_[X86_REG_EBP] = ucontext->uc_mcontext.ebp;
  88. regs_[X86_REG_ESP] = ucontext->uc_mcontext.esp;
  89. regs_[X86_REG_EBX] = ucontext->uc_mcontext.ebx;
  90. regs_[X86_REG_EDX] = ucontext->uc_mcontext.edx;
  91. regs_[X86_REG_ECX] = ucontext->uc_mcontext.ecx;
  92. regs_[X86_REG_EAX] = ucontext->uc_mcontext.eax;
  93. regs_[X86_REG_EIP] = ucontext->uc_mcontext.eip;
  94. }
  95. Regs* RegsX86::CreateFromUcontext(void* ucontext) {
  96. x86_ucontext_t* x86_ucontext = reinterpret_cast<x86_ucontext_t*>(ucontext);
  97. RegsX86* regs = new RegsX86();
  98. regs->SetFromUcontext(x86_ucontext);
  99. return regs;
  100. }
  101. bool RegsX86::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
  102. uint64_t data;
  103. Memory* elf_memory = elf->memory();
  104. // Read from elf memory since it is usually more expensive to read from
  105. // process memory.
  106. if (!elf_memory->ReadFully(rel_pc, &data, sizeof(data))) {
  107. return false;
  108. }
  109. if (data == 0x80cd00000077b858ULL) {
  110. // Without SA_SIGINFO set, the return sequence is:
  111. //
  112. // __restore:
  113. // 0x58 pop %eax
  114. // 0xb8 0x77 0x00 0x00 0x00 movl 0x77,%eax
  115. // 0xcd 0x80 int 0x80
  116. //
  117. // SP points at arguments:
  118. // int signum
  119. // struct sigcontext (same format as mcontext)
  120. struct x86_mcontext_t context;
  121. if (!process_memory->ReadFully(regs_[X86_REG_SP] + 4, &context, sizeof(context))) {
  122. return false;
  123. }
  124. regs_[X86_REG_EBP] = context.ebp;
  125. regs_[X86_REG_ESP] = context.esp;
  126. regs_[X86_REG_EBX] = context.ebx;
  127. regs_[X86_REG_EDX] = context.edx;
  128. regs_[X86_REG_ECX] = context.ecx;
  129. regs_[X86_REG_EAX] = context.eax;
  130. regs_[X86_REG_EIP] = context.eip;
  131. return true;
  132. } else if ((data & 0x00ffffffffffffffULL) == 0x0080cd000000adb8ULL) {
  133. // With SA_SIGINFO set, the return sequence is:
  134. //
  135. // __restore_rt:
  136. // 0xb8 0xad 0x00 0x00 0x00 movl 0xad,%eax
  137. // 0xcd 0x80 int 0x80
  138. //
  139. // SP points at arguments:
  140. // int signum
  141. // siginfo*
  142. // ucontext*
  143. // Get the location of the sigcontext data.
  144. uint32_t ptr;
  145. if (!process_memory->ReadFully(regs_[X86_REG_SP] + 8, &ptr, sizeof(ptr))) {
  146. return false;
  147. }
  148. // Only read the portion of the data structure we care about.
  149. x86_ucontext_t x86_ucontext;
  150. if (!process_memory->ReadFully(ptr + 0x14, &x86_ucontext.uc_mcontext, sizeof(x86_mcontext_t))) {
  151. return false;
  152. }
  153. SetFromUcontext(&x86_ucontext);
  154. return true;
  155. }
  156. return false;
  157. }
  158. Regs* RegsX86::Clone() {
  159. return new RegsX86(*this);
  160. }
  161. } // namespace unwindstack