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