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