ThreadElfCore.cpp revision 269024
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/Target/RegisterContext.h" 12#include "lldb/Target/StopInfo.h" 13#include "lldb/Target/Target.h" 14#include "lldb/Target/Unwind.h" 15#include "ProcessPOSIXLog.h" 16 17#include "ThreadElfCore.h" 18#include "ProcessElfCore.h" 19#include "RegisterContextLinux_x86_64.h" 20#include "RegisterContextFreeBSD_i386.h" 21#include "RegisterContextFreeBSD_mips64.h" 22#include "RegisterContextFreeBSD_x86_64.h" 23#include "RegisterContextPOSIXCore_mips64.h" 24#include "RegisterContextPOSIXCore_x86_64.h" 25 26using namespace lldb; 27using namespace lldb_private; 28 29//---------------------------------------------------------------------- 30// Construct a Thread object with given data 31//---------------------------------------------------------------------- 32ThreadElfCore::ThreadElfCore (Process &process, tid_t tid, 33 const ThreadData &td) : 34 Thread(process, tid), 35 m_thread_name(td.name), 36 m_thread_reg_ctx_sp (), 37 m_signo(td.signo), 38 m_gpregset_data(td.gpregset), 39 m_fpregset_data(td.fpregset) 40{ 41} 42 43ThreadElfCore::~ThreadElfCore () 44{ 45 DestroyThread(); 46} 47 48void 49ThreadElfCore::RefreshStateAfterStop() 50{ 51 GetRegisterContext()->InvalidateIfNeeded (false); 52} 53 54void 55ThreadElfCore::ClearStackFrames () 56{ 57 Unwind *unwinder = GetUnwinder (); 58 if (unwinder) 59 unwinder->Clear(); 60 Thread::ClearStackFrames(); 61} 62 63RegisterContextSP 64ThreadElfCore::GetRegisterContext () 65{ 66 if (m_reg_context_sp.get() == NULL) { 67 m_reg_context_sp = CreateRegisterContextForFrame (NULL); 68 } 69 return m_reg_context_sp; 70} 71 72RegisterContextSP 73ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame) 74{ 75 RegisterContextSP reg_ctx_sp; 76 uint32_t concrete_frame_idx = 0; 77 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 78 79 if (frame) 80 concrete_frame_idx = frame->GetConcreteFrameIndex (); 81 82 if (concrete_frame_idx == 0) 83 { 84 if (m_thread_reg_ctx_sp) 85 return m_thread_reg_ctx_sp; 86 87 ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get()); 88 ArchSpec arch = process->GetArchitecture(); 89 RegisterInfoInterface *reg_interface = NULL; 90 91 switch (arch.GetTriple().getOS()) 92 { 93 case llvm::Triple::FreeBSD: 94 { 95 switch (arch.GetMachine()) 96 { 97 case llvm::Triple::mips64: 98 reg_interface = new RegisterContextFreeBSD_mips64(arch); 99 break; 100 case llvm::Triple::x86: 101 reg_interface = new RegisterContextFreeBSD_i386(arch); 102 break; 103 case llvm::Triple::x86_64: 104 reg_interface = new RegisterContextFreeBSD_x86_64(arch); 105 break; 106 default: 107 break; 108 } 109 break; 110 } 111 112 case llvm::Triple::Linux: 113 { 114 switch (arch.GetMachine()) 115 { 116 case llvm::Triple::x86_64: 117 reg_interface = new RegisterContextLinux_x86_64(arch); 118 break; 119 default: 120 break; 121 } 122 break; 123 } 124 125 default: 126 break; 127 } 128 129 if (!reg_interface) { 130 if (log) 131 log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported", 132 __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); 133 assert (false && "Architecture or OS not supported"); 134 } 135 136 switch (arch.GetMachine()) 137 { 138 case llvm::Triple::mips64: 139 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 140 break; 141 case llvm::Triple::x86: 142 case llvm::Triple::x86_64: 143 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 144 break; 145 default: 146 break; 147 } 148 149 reg_ctx_sp = m_thread_reg_ctx_sp; 150 } 151 else if (m_unwinder_ap.get()) 152 { 153 reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame); 154 } 155 return reg_ctx_sp; 156} 157 158bool 159ThreadElfCore::CalculateStopInfo () 160{ 161 ProcessSP process_sp (GetProcess()); 162 if (process_sp) 163 { 164 SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo)); 165 return true; 166 } 167 return false; 168} 169 170//---------------------------------------------------------------- 171// Parse PRSTATUS from NOTE entry 172//---------------------------------------------------------------- 173ELFLinuxPrStatus::ELFLinuxPrStatus() 174{ 175 memset(this, 0, sizeof(ELFLinuxPrStatus)); 176} 177 178bool 179ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) 180{ 181 ByteOrder byteorder = data.GetByteOrder(); 182 size_t len; 183 switch(arch.GetCore()) 184 { 185 case ArchSpec::eCore_x86_64_x86_64: 186 len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this); 187 return len == ELFLINUXPRSTATUS64_SIZE; 188 default: 189 return false; 190 } 191} 192 193//---------------------------------------------------------------- 194// Parse PRPSINFO from NOTE entry 195//---------------------------------------------------------------- 196ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() 197{ 198 memset(this, 0, sizeof(ELFLinuxPrPsInfo)); 199} 200 201bool 202ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) 203{ 204 ByteOrder byteorder = data.GetByteOrder(); 205 size_t len; 206 switch(arch.GetCore()) 207 { 208 case ArchSpec::eCore_x86_64_x86_64: 209 len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this); 210 return len == ELFLINUXPRPSINFO64_SIZE; 211 default: 212 return false; 213 } 214} 215 216