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_i386.h" 23 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" 24 #include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h" 25 #include "Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h" 26 #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" 27 #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" 28 #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" 29 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" 30 #include "RegisterContextPOSIXCore_arm.h" 31 #include "RegisterContextPOSIXCore_arm64.h" 32 #include "RegisterContextPOSIXCore_mips64.h" 33 #include "RegisterContextPOSIXCore_powerpc.h" 34 #include "RegisterContextPOSIXCore_s390x.h" 35 #include "RegisterContextPOSIXCore_x86_64.h" 36 37 using namespace lldb; 38 using namespace lldb_private; 39 40 //---------------------------------------------------------------------- 41 // Construct a Thread object with given data 42 //---------------------------------------------------------------------- 43 ThreadElfCore::ThreadElfCore (Process &process, const ThreadData &td) : 44 Thread(process, td.tid), 45 m_thread_name(td.name), 46 m_thread_reg_ctx_sp (), 47 m_signo(td.signo), 48 m_gpregset_data(td.gpregset), 49 m_fpregset_data(td.fpregset), 50 m_vregset_data(td.vregset) 51 { 52 } 53 54 ThreadElfCore::~ThreadElfCore () 55 { 56 DestroyThread(); 57 } 58 59 void 60 ThreadElfCore::RefreshStateAfterStop() 61 { 62 GetRegisterContext()->InvalidateIfNeeded (false); 63 } 64 65 void 66 ThreadElfCore::ClearStackFrames () 67 { 68 Unwind *unwinder = GetUnwinder (); 69 if (unwinder) 70 unwinder->Clear(); 71 Thread::ClearStackFrames(); 72 } 73 74 RegisterContextSP 75 ThreadElfCore::GetRegisterContext () 76 { 77 if (m_reg_context_sp.get() == NULL) { 78 m_reg_context_sp = CreateRegisterContextForFrame (NULL); 79 } 80 return m_reg_context_sp; 81 } 82 83 RegisterContextSP 84 ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame) 85 { 86 RegisterContextSP reg_ctx_sp; 87 uint32_t concrete_frame_idx = 0; 88 Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); 89 90 if (frame) 91 concrete_frame_idx = frame->GetConcreteFrameIndex (); 92 93 if (concrete_frame_idx == 0) 94 { 95 if (m_thread_reg_ctx_sp) 96 return m_thread_reg_ctx_sp; 97 98 ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get()); 99 ArchSpec arch = process->GetArchitecture(); 100 RegisterInfoInterface *reg_interface = NULL; 101 102 switch (arch.GetTriple().getOS()) 103 { 104 case llvm::Triple::FreeBSD: 105 { 106 switch (arch.GetMachine()) 107 { 108 case llvm::Triple::aarch64: 109 reg_interface = new RegisterContextFreeBSD_arm64(arch); 110 break; 111 case llvm::Triple::arm: 112 reg_interface = new RegisterContextFreeBSD_arm(arch); 113 break; 114 case llvm::Triple::ppc: 115 reg_interface = new RegisterContextFreeBSD_powerpc32(arch); 116 break; 117 case llvm::Triple::ppc64: 118 reg_interface = new RegisterContextFreeBSD_powerpc64(arch); 119 break; 120 case llvm::Triple::mips64: 121 reg_interface = new RegisterContextFreeBSD_mips64(arch); 122 break; 123 case llvm::Triple::x86: 124 reg_interface = new RegisterContextFreeBSD_i386(arch); 125 break; 126 case llvm::Triple::x86_64: 127 reg_interface = new RegisterContextFreeBSD_x86_64(arch); 128 break; 129 default: 130 break; 131 } 132 break; 133 } 134 135 case llvm::Triple::Linux: 136 { 137 switch (arch.GetMachine()) 138 { 139 case llvm::Triple::arm: 140 reg_interface = new RegisterContextLinux_arm(arch); 141 break; 142 case llvm::Triple::aarch64: 143 reg_interface = new RegisterContextLinux_arm64(arch); 144 break; 145 case llvm::Triple::systemz: 146 reg_interface = new RegisterContextLinux_s390x(arch); 147 break; 148 case llvm::Triple::x86: 149 reg_interface = new RegisterContextLinux_i386(arch); 150 break; 151 case llvm::Triple::x86_64: 152 reg_interface = new RegisterContextLinux_x86_64(arch); 153 break; 154 default: 155 break; 156 } 157 break; 158 } 159 160 default: 161 break; 162 } 163 164 if (!reg_interface) { 165 if (log) 166 log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported", 167 __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); 168 assert (false && "Architecture or OS not supported"); 169 } 170 171 switch (arch.GetMachine()) 172 { 173 case llvm::Triple::aarch64: 174 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 175 break; 176 case llvm::Triple::arm: 177 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 178 break; 179 case llvm::Triple::mips64: 180 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 181 break; 182 case llvm::Triple::ppc: 183 case llvm::Triple::ppc64: 184 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data)); 185 break; 186 case llvm::Triple::systemz: 187 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 188 break; 189 case llvm::Triple::x86: 190 case llvm::Triple::x86_64: 191 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 192 break; 193 default: 194 break; 195 } 196 197 reg_ctx_sp = m_thread_reg_ctx_sp; 198 } 199 else if (m_unwinder_ap.get()) 200 { 201 reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame); 202 } 203 return reg_ctx_sp; 204 } 205 206 bool 207 ThreadElfCore::CalculateStopInfo () 208 { 209 ProcessSP process_sp (GetProcess()); 210 if (process_sp) 211 { 212 SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo)); 213 return true; 214 } 215 return false; 216 } 217 218 //---------------------------------------------------------------- 219 // Parse PRSTATUS from NOTE entry 220 //---------------------------------------------------------------- 221 ELFLinuxPrStatus::ELFLinuxPrStatus() 222 { 223 memset(this, 0, sizeof(ELFLinuxPrStatus)); 224 } 225 226 Error 227 ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) 228 { 229 Error error; 230 ByteOrder byteorder = data.GetByteOrder(); 231 if (GetSize(arch) > data.GetByteSize()) 232 { 233 error.SetErrorStringWithFormat("NT_PRSTATUS size should be %lu, but the remaining bytes are: %" PRIu64, 234 GetSize(arch), data.GetByteSize()); 235 return error; 236 } 237 238 switch(arch.GetCore()) 239 { 240 case ArchSpec::eCore_s390x_generic: 241 case ArchSpec::eCore_x86_64_x86_64: 242 data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this); 243 break; 244 case ArchSpec::eCore_x86_32_i386: 245 case ArchSpec::eCore_x86_32_i486: 246 { 247 // Parsing from a 32 bit ELF core file, and populating/reusing the structure 248 // properly, because the struct is for the 64 bit version 249 offset_t offset = 0; 250 si_signo = data.GetU32(&offset); 251 si_code = data.GetU32(&offset); 252 si_errno = data.GetU32(&offset); 253 254 pr_cursig = data.GetU16(&offset); 255 offset += 2; // pad 256 257 pr_sigpend = data.GetU32(&offset); 258 pr_sighold = data.GetU32(&offset); 259 260 pr_pid = data.GetU32(&offset); 261 pr_ppid = data.GetU32(&offset); 262 pr_pgrp = data.GetU32(&offset); 263 pr_sid = data.GetU32(&offset); 264 265 pr_utime.tv_sec = data.GetU32(&offset); 266 pr_utime.tv_usec = data.GetU32(&offset); 267 268 pr_stime.tv_sec = data.GetU32(&offset); 269 pr_stime.tv_usec = data.GetU32(&offset); 270 271 pr_cutime.tv_sec = data.GetU32(&offset); 272 pr_cutime.tv_usec = data.GetU32(&offset); 273 274 pr_cstime.tv_sec = data.GetU32(&offset); 275 pr_cstime.tv_usec = data.GetU32(&offset); 276 277 break; 278 } 279 default: 280 error.SetErrorStringWithFormat("ELFLinuxPrStatus::%s Unknown architecture", __FUNCTION__); 281 break; 282 } 283 284 return error; 285 } 286 287 //---------------------------------------------------------------- 288 // Parse PRPSINFO from NOTE entry 289 //---------------------------------------------------------------- 290 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() 291 { 292 memset(this, 0, sizeof(ELFLinuxPrPsInfo)); 293 } 294 295 Error 296 ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) 297 { 298 Error error; 299 ByteOrder byteorder = data.GetByteOrder(); 300 if (GetSize(arch) > data.GetByteSize()) 301 { 302 error.SetErrorStringWithFormat("NT_PRPSINFO size should be %lu, but the remaining bytes are: %" PRIu64, 303 GetSize(arch), data.GetByteSize()); 304 return error; 305 } 306 307 switch(arch.GetCore()) 308 { 309 case ArchSpec::eCore_s390x_generic: 310 case ArchSpec::eCore_x86_64_x86_64: 311 data.ExtractBytes(0, sizeof(ELFLinuxPrPsInfo), byteorder, this); 312 break; 313 case ArchSpec::eCore_x86_32_i386: 314 case ArchSpec::eCore_x86_32_i486: 315 { 316 // Parsing from a 32 bit ELF core file, and populating/reusing the structure 317 // properly, because the struct is for the 64 bit version 318 size_t size = 0; 319 offset_t offset = 0; 320 321 pr_state = data.GetU8(&offset); 322 pr_sname = data.GetU8(&offset); 323 pr_zomb = data.GetU8(&offset); 324 pr_nice = data.GetU8(&offset); 325 326 pr_flag = data.GetU32(&offset); 327 pr_uid = data.GetU16(&offset); 328 pr_gid = data.GetU16(&offset); 329 330 pr_pid = data.GetU32(&offset); 331 pr_ppid = data.GetU32(&offset); 332 pr_pgrp = data.GetU32(&offset); 333 pr_sid = data.GetU32(&offset); 334 335 size = 16; 336 data.ExtractBytes(offset, size, byteorder, pr_fname); 337 offset += size; 338 339 size = 80; 340 data.ExtractBytes(offset, size, byteorder, pr_psargs); 341 offset += size; 342 343 break; 344 } 345 default: 346 error.SetErrorStringWithFormat("ELFLinuxPrPsInfo::%s Unknown architecture", __FUNCTION__); 347 break; 348 } 349 350 return error; 351 } 352 353