ThreadElfCore.cpp revision 26345cbada66df8e698111cdf8d1689ccefe8331
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 "RegisterContextCoreLinux_x86_64.h" 20 21using namespace lldb; 22using namespace lldb_private; 23 24//---------------------------------------------------------------------- 25// Construct a Thread object with given PRSTATUS, PRPSINFO and FPREGSET 26//---------------------------------------------------------------------- 27ThreadElfCore::ThreadElfCore (Process &process, tid_t tid, DataExtractor prstatus, 28 DataExtractor prpsinfo, DataExtractor fpregset) : 29 Thread(process, tid), 30 m_thread_reg_ctx_sp () 31{ 32 ProcessElfCore *pr = static_cast<ProcessElfCore *>(GetProcess().get()); 33 ArchSpec arch = pr->GetArchitecture(); 34 35 /* Parse the datastructures from the file */ 36 m_prstatus.Parse(prstatus, arch); 37 m_prpsinfo.Parse(prpsinfo, arch); 38 39 m_prstatus_data = prstatus; 40 m_fpregset_data = fpregset; 41 42 m_thread_name = std::string(m_prpsinfo.pr_fname); 43} 44 45ThreadElfCore::~ThreadElfCore () 46{ 47 DestroyThread(); 48} 49 50void 51ThreadElfCore::RefreshStateAfterStop() 52{ 53 GetRegisterContext()->InvalidateIfNeeded (false); 54} 55 56void 57ThreadElfCore::ClearStackFrames () 58{ 59 Unwind *unwinder = GetUnwinder (); 60 if (unwinder) 61 unwinder->Clear(); 62 Thread::ClearStackFrames(); 63} 64 65RegisterContextSP 66ThreadElfCore::GetRegisterContext () 67{ 68 if (m_reg_context_sp.get() == NULL) { 69 m_reg_context_sp = CreateRegisterContextForFrame (NULL); 70 } 71 return m_reg_context_sp; 72} 73 74RegisterContextSP 75ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame) 76{ 77 RegisterContextSP reg_ctx_sp; 78 uint32_t concrete_frame_idx = 0; 79 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 80 81 if (frame) 82 concrete_frame_idx = frame->GetConcreteFrameIndex (); 83 84 if (concrete_frame_idx == 0) 85 { 86 if (m_thread_reg_ctx_sp) 87 return m_thread_reg_ctx_sp; 88 89 ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get()); 90 ArchSpec arch = process->GetArchitecture(); 91 size_t header_size = ELFPrStatus::GetSize(arch); 92 size_t len = m_prstatus_data.GetByteSize() - header_size; 93 DataExtractor gpregset_data = DataExtractor(m_prstatus_data, header_size, len); 94 switch (arch.GetMachine()) 95 { 96 case llvm::Triple::x86_64: 97 m_thread_reg_ctx_sp.reset(new RegisterContextCoreLinux_x86_64 (*this, gpregset_data, m_fpregset_data)); 98 break; 99 default: 100 if (log) 101 log->Printf ("elf-core::%s:: Architecture(%d) not supported", 102 __FUNCTION__, arch.GetMachine()); 103 } 104 reg_ctx_sp = m_thread_reg_ctx_sp; 105 } 106 else if (m_unwinder_ap.get()) 107 { 108 reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame); 109 } 110 return reg_ctx_sp; 111} 112 113bool 114ThreadElfCore::CalculateStopInfo () 115{ 116 ProcessSP process_sp (GetProcess()); 117 if (process_sp) 118 { 119 SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_prstatus.pr_cursig)); 120 return true; 121 } 122 return false; 123} 124 125//---------------------------------------------------------------- 126// Parse PRSTATUS from NOTE entry 127//---------------------------------------------------------------- 128ELFPrStatus::ELFPrStatus() 129{ 130 memset(this, 0, sizeof(ELFPrStatus)); 131} 132 133bool 134ELFPrStatus::Parse(DataExtractor &data, ArchSpec &arch) 135{ 136 ByteOrder byteorder = data.GetByteOrder(); 137 size_t len; 138 switch(arch.GetCore()) 139 { 140 case ArchSpec::eCore_x86_64_x86_64: 141 len = data.ExtractBytes(0, ELFPRSTATUS64_SIZE, byteorder, this); 142 return len == ELFPRSTATUS64_SIZE; 143 default: 144 return false; 145 } 146} 147 148//---------------------------------------------------------------- 149// Parse PRPSINFO from NOTE entry 150//---------------------------------------------------------------- 151ELFPrPsInfo::ELFPrPsInfo() 152{ 153 memset(this, 0, sizeof(ELFPrPsInfo)); 154} 155 156bool 157ELFPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) 158{ 159 ByteOrder byteorder = data.GetByteOrder(); 160 size_t len; 161 switch(arch.GetCore()) 162 { 163 case ArchSpec::eCore_x86_64_x86_64: 164 len = data.ExtractBytes(0, ELFPRPSINFO64_SIZE, byteorder, this); 165 return len == ELFPRPSINFO64_SIZE; 166 default: 167 return false; 168 } 169} 170 171