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