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