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