1 //===-- ThreadElfCore.cpp --------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Core/DataExtractor.h" 11 #include "lldb/Core/Log.h" 12 #include "lldb/Target/RegisterContext.h" 13 #include "lldb/Target/StopInfo.h" 14 #include "lldb/Target/Target.h" 15 #include "lldb/Target/Unwind.h" 16 17 #include "ThreadElfCore.h" 18 #include "ProcessElfCore.h" 19 #include "Plugins/Process/Utility/RegisterContextLinux_arm.h" 20 #include "Plugins/Process/Utility/RegisterContextLinux_arm64.h" 21 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" 22 #include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h" 23 #include "Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h" 24 #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" 25 #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" 26 #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" 27 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" 28 #include "RegisterContextPOSIXCore_arm.h" 29 #include "RegisterContextPOSIXCore_arm64.h" 30 #include "RegisterContextPOSIXCore_mips64.h" 31 #include "RegisterContextPOSIXCore_powerpc.h" 32 #include "RegisterContextPOSIXCore_x86_64.h" 33 34 using namespace lldb; 35 using namespace lldb_private; 36 37 //---------------------------------------------------------------------- 38 // Construct a Thread object with given data 39 //---------------------------------------------------------------------- 40 ThreadElfCore::ThreadElfCore (Process &process, const ThreadData &td) : 41 Thread(process, td.tid), 42 m_thread_name(td.name), 43 m_thread_reg_ctx_sp (), 44 m_signo(td.signo), 45 m_gpregset_data(td.gpregset), 46 m_fpregset_data(td.fpregset), 47 m_vregset_data(td.vregset) 48 { 49 } 50 51 ThreadElfCore::~ThreadElfCore () 52 { 53 DestroyThread(); 54 } 55 56 void 57 ThreadElfCore::RefreshStateAfterStop() 58 { 59 GetRegisterContext()->InvalidateIfNeeded (false); 60 } 61 62 void 63 ThreadElfCore::ClearStackFrames () 64 { 65 Unwind *unwinder = GetUnwinder (); 66 if (unwinder) 67 unwinder->Clear(); 68 Thread::ClearStackFrames(); 69 } 70 71 RegisterContextSP 72 ThreadElfCore::GetRegisterContext () 73 { 74 if (m_reg_context_sp.get() == NULL) { 75 m_reg_context_sp = CreateRegisterContextForFrame (NULL); 76 } 77 return m_reg_context_sp; 78 } 79 80 RegisterContextSP 81 ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame) 82 { 83 RegisterContextSP reg_ctx_sp; 84 uint32_t concrete_frame_idx = 0; 85 Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); 86 87 if (frame) 88 concrete_frame_idx = frame->GetConcreteFrameIndex (); 89 90 if (concrete_frame_idx == 0) 91 { 92 if (m_thread_reg_ctx_sp) 93 return m_thread_reg_ctx_sp; 94 95 ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get()); 96 ArchSpec arch = process->GetArchitecture(); 97 RegisterInfoInterface *reg_interface = NULL; 98 99 switch (arch.GetTriple().getOS()) 100 { 101 case llvm::Triple::FreeBSD: 102 { 103 switch (arch.GetMachine()) 104 { 105 case llvm::Triple::aarch64: 106 reg_interface = new RegisterContextFreeBSD_arm64(arch); 107 break; 108 case llvm::Triple::arm: 109 reg_interface = new RegisterContextFreeBSD_arm(arch); 110 break; 111 case llvm::Triple::ppc: 112 reg_interface = new RegisterContextFreeBSD_powerpc32(arch); 113 break; 114 case llvm::Triple::ppc64: 115 reg_interface = new RegisterContextFreeBSD_powerpc64(arch); 116 break; 117 case llvm::Triple::mips64: 118 reg_interface = new RegisterContextFreeBSD_mips64(arch); 119 break; 120 case llvm::Triple::x86: 121 reg_interface = new RegisterContextFreeBSD_i386(arch); 122 break; 123 case llvm::Triple::x86_64: 124 reg_interface = new RegisterContextFreeBSD_x86_64(arch); 125 break; 126 default: 127 break; 128 } 129 break; 130 } 131 132 case llvm::Triple::Linux: 133 { 134 switch (arch.GetMachine()) 135 { 136 case llvm::Triple::arm: 137 reg_interface = new RegisterContextLinux_arm(arch); 138 break; 139 case llvm::Triple::aarch64: 140 reg_interface = new RegisterContextLinux_arm64(arch); 141 break; 142 case llvm::Triple::x86_64: 143 reg_interface = new RegisterContextLinux_x86_64(arch); 144 break; 145 default: 146 break; 147 } 148 break; 149 } 150 151 default: 152 break; 153 } 154 155 if (!reg_interface) { 156 if (log) 157 log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported", 158 __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); 159 assert (false && "Architecture or OS not supported"); 160 } 161 162 switch (arch.GetMachine()) 163 { 164 case llvm::Triple::aarch64: 165 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 166 break; 167 case llvm::Triple::arm: 168 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 169 break; 170 case llvm::Triple::mips64: 171 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 172 break; 173 case llvm::Triple::ppc: 174 case llvm::Triple::ppc64: 175 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data)); 176 break; 177 case llvm::Triple::x86: 178 case llvm::Triple::x86_64: 179 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 180 break; 181 default: 182 break; 183 } 184 185 reg_ctx_sp = m_thread_reg_ctx_sp; 186 } 187 else if (m_unwinder_ap.get()) 188 { 189 reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame); 190 } 191 return reg_ctx_sp; 192 } 193 194 bool 195 ThreadElfCore::CalculateStopInfo () 196 { 197 ProcessSP process_sp (GetProcess()); 198 if (process_sp) 199 { 200 SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo)); 201 return true; 202 } 203 return false; 204 } 205 206 //---------------------------------------------------------------- 207 // Parse PRSTATUS from NOTE entry 208 //---------------------------------------------------------------- 209 ELFLinuxPrStatus::ELFLinuxPrStatus() 210 { 211 memset(this, 0, sizeof(ELFLinuxPrStatus)); 212 } 213 214 bool 215 ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) 216 { 217 ByteOrder byteorder = data.GetByteOrder(); 218 size_t len; 219 switch(arch.GetCore()) 220 { 221 case ArchSpec::eCore_x86_64_x86_64: 222 len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this); 223 return len == ELFLINUXPRSTATUS64_SIZE; 224 default: 225 return false; 226 } 227 } 228 229 //---------------------------------------------------------------- 230 // Parse PRPSINFO from NOTE entry 231 //---------------------------------------------------------------- 232 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() 233 { 234 memset(this, 0, sizeof(ELFLinuxPrPsInfo)); 235 } 236 237 bool 238 ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) 239 { 240 ByteOrder byteorder = data.GetByteOrder(); 241 size_t len; 242 switch(arch.GetCore()) 243 { 244 case ArchSpec::eCore_x86_64_x86_64: 245 len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this); 246 return len == ELFLINUXPRPSINFO64_SIZE; 247 default: 248 return false; 249 } 250 } 251 252