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