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 m_vregset_data(td.vregset) 43 { 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 (GetLogIfAllCategoriesSet(LIBLLDB_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 RegisterInfoInterface *reg_interface = NULL; 93 94 switch (arch.GetTriple().getOS()) 95 { 96 case llvm::Triple::FreeBSD: 97 { 98 switch (arch.GetMachine()) 99 { 100 case llvm::Triple::ppc: 101 reg_interface = new RegisterContextFreeBSD_powerpc32(arch); 102 break; 103 case llvm::Triple::ppc64: 104 reg_interface = new RegisterContextFreeBSD_powerpc64(arch); 105 break; 106 case llvm::Triple::mips64: 107 reg_interface = new RegisterContextFreeBSD_mips64(arch); 108 break; 109 case llvm::Triple::x86: 110 reg_interface = new RegisterContextFreeBSD_i386(arch); 111 break; 112 case llvm::Triple::x86_64: 113 reg_interface = new RegisterContextFreeBSD_x86_64(arch); 114 break; 115 default: 116 break; 117 } 118 break; 119 } 120 121 case llvm::Triple::Linux: 122 { 123 switch (arch.GetMachine()) 124 { 125 case llvm::Triple::x86_64: 126 reg_interface = new RegisterContextLinux_x86_64(arch); 127 break; 128 default: 129 break; 130 } 131 break; 132 } 133 134 default: 135 break; 136 } 137 138 if (!reg_interface) { 139 if (log) 140 log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported", 141 __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); 142 assert (false && "Architecture or OS not supported"); 143 } 144 145 switch (arch.GetMachine()) 146 { 147 case llvm::Triple::mips64: 148 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 149 break; 150 case llvm::Triple::ppc: 151 case llvm::Triple::ppc64: 152 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data)); 153 break; 154 case llvm::Triple::x86: 155 case llvm::Triple::x86_64: 156 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 157 break; 158 default: 159 break; 160 } 161 162 reg_ctx_sp = m_thread_reg_ctx_sp; 163 } 164 else if (m_unwinder_ap.get()) 165 { 166 reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame); 167 } 168 return reg_ctx_sp; 169 } 170 171 bool 172 ThreadElfCore::CalculateStopInfo () 173 { 174 ProcessSP process_sp (GetProcess()); 175 if (process_sp) 176 { 177 SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo)); 178 return true; 179 } 180 return false; 181 } 182 183 //---------------------------------------------------------------- 184 // Parse PRSTATUS from NOTE entry 185 //---------------------------------------------------------------- 186 ELFLinuxPrStatus::ELFLinuxPrStatus() 187 { 188 memset(this, 0, sizeof(ELFLinuxPrStatus)); 189 } 190 191 bool 192 ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) 193 { 194 ByteOrder byteorder = data.GetByteOrder(); 195 size_t len; 196 switch(arch.GetCore()) 197 { 198 case ArchSpec::eCore_x86_64_x86_64: 199 len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this); 200 return len == ELFLINUXPRSTATUS64_SIZE; 201 default: 202 return false; 203 } 204 } 205 206 //---------------------------------------------------------------- 207 // Parse PRPSINFO from NOTE entry 208 //---------------------------------------------------------------- 209 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() 210 { 211 memset(this, 0, sizeof(ELFLinuxPrPsInfo)); 212 } 213 214 bool 215 ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) 216 { 217 ByteOrder byteorder = data.GetByteOrder(); 218 size_t len; 219 switch(arch.GetCore()) 220 { 221 case ArchSpec::eCore_x86_64_x86_64: 222 len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this); 223 return len == ELFLINUXPRPSINFO64_SIZE; 224 default: 225 return false; 226 } 227 } 228 229