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