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