ThreadElfCore.cpp revision 327952
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/Target/RegisterContext.h" 11#include "lldb/Target/StopInfo.h" 12#include "lldb/Target/Target.h" 13#include "lldb/Target/Unwind.h" 14#include "lldb/Utility/DataExtractor.h" 15#include "lldb/Utility/Log.h" 16 17#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" 18#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" 19#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" 20#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" 21#include "Plugins/Process/Utility/RegisterContextLinux_i386.h" 22#include "Plugins/Process/Utility/RegisterContextLinux_mips.h" 23#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h" 24#ifdef LLDB_ENABLE_ALL 25#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h" 26#endif // LLDB_ENABLE_ALL 27#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" 28#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" 29#include "Plugins/Process/Utility/RegisterContextOpenBSD_i386.h" 30#include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h" 31#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h" 32#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" 33#include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h" 34#include "ProcessElfCore.h" 35#include "RegisterContextPOSIXCore_arm.h" 36#include "RegisterContextPOSIXCore_arm64.h" 37#include "RegisterContextPOSIXCore_mips64.h" 38#include "RegisterContextPOSIXCore_powerpc.h" 39#include "RegisterContextPOSIXCore_ppc64le.h" 40#ifdef LLDB_ENABLE_ALL 41#include "RegisterContextPOSIXCore_s390x.h" 42#endif // LLDB_ENABLE_ALL 43#include "RegisterContextPOSIXCore_x86_64.h" 44#include "ThreadElfCore.h" 45 46using namespace lldb; 47using namespace lldb_private; 48 49//---------------------------------------------------------------------- 50// Construct a Thread object with given data 51//---------------------------------------------------------------------- 52ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td) 53 : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(), 54 m_signo(td.signo), m_gpregset_data(td.gpregset), m_notes(td.notes) {} 55 56ThreadElfCore::~ThreadElfCore() { DestroyThread(); } 57 58void ThreadElfCore::RefreshStateAfterStop() { 59 GetRegisterContext()->InvalidateIfNeeded(false); 60} 61 62void ThreadElfCore::ClearStackFrames() { 63 Unwind *unwinder = GetUnwinder(); 64 if (unwinder) 65 unwinder->Clear(); 66 Thread::ClearStackFrames(); 67} 68 69RegisterContextSP ThreadElfCore::GetRegisterContext() { 70 if (m_reg_context_sp.get() == NULL) { 71 m_reg_context_sp = CreateRegisterContextForFrame(NULL); 72 } 73 return m_reg_context_sp; 74} 75 76RegisterContextSP 77ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { 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 if (m_thread_reg_ctx_sp) 87 return m_thread_reg_ctx_sp; 88 89 ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get()); 90 ArchSpec arch = process->GetArchitecture(); 91 RegisterInfoInterface *reg_interface = NULL; 92 93 switch (arch.GetTriple().getOS()) { 94 case llvm::Triple::FreeBSD: { 95 switch (arch.GetMachine()) { 96 case llvm::Triple::aarch64: 97 reg_interface = new RegisterInfoPOSIX_arm64(arch); 98 break; 99 case llvm::Triple::arm: 100 reg_interface = new RegisterInfoPOSIX_arm(arch); 101 break; 102 case llvm::Triple::ppc: 103 reg_interface = new RegisterContextFreeBSD_powerpc32(arch); 104 break; 105 case llvm::Triple::ppc64: 106 reg_interface = new RegisterContextFreeBSD_powerpc64(arch); 107 break; 108 case llvm::Triple::mips64: 109 reg_interface = new RegisterContextFreeBSD_mips64(arch); 110 break; 111 case llvm::Triple::x86: 112 reg_interface = new RegisterContextFreeBSD_i386(arch); 113 break; 114 case llvm::Triple::x86_64: 115 reg_interface = new RegisterContextFreeBSD_x86_64(arch); 116 break; 117 default: 118 break; 119 } 120 break; 121 } 122 123 case llvm::Triple::NetBSD: { 124 switch (arch.GetMachine()) { 125 case llvm::Triple::x86_64: 126 reg_interface = new RegisterContextNetBSD_x86_64(arch); 127 break; 128 default: 129 break; 130 } 131 break; 132 } 133 134 case llvm::Triple::Linux: { 135 switch (arch.GetMachine()) { 136 case llvm::Triple::arm: 137 reg_interface = new RegisterInfoPOSIX_arm(arch); 138 break; 139 case llvm::Triple::aarch64: 140 reg_interface = new RegisterInfoPOSIX_arm64(arch); 141 break; 142 case llvm::Triple::mipsel: 143 case llvm::Triple::mips: 144 reg_interface = new RegisterContextLinux_mips(arch); 145 break; 146 case llvm::Triple::mips64el: 147 case llvm::Triple::mips64: 148 reg_interface = new RegisterContextLinux_mips64(arch); 149 break; 150 case llvm::Triple::ppc64le: 151 reg_interface = new RegisterInfoPOSIX_ppc64le(arch); 152 break; 153#ifdef LLDB_ENABLE_ALL 154 case llvm::Triple::systemz: 155 reg_interface = new RegisterContextLinux_s390x(arch); 156 break; 157#endif // LLDB_ENABLE_ALL 158 case llvm::Triple::x86: 159 reg_interface = new RegisterContextLinux_i386(arch); 160 break; 161 case llvm::Triple::x86_64: 162 reg_interface = new RegisterContextLinux_x86_64(arch); 163 break; 164 default: 165 break; 166 } 167 break; 168 } 169 170 case llvm::Triple::OpenBSD: { 171 switch (arch.GetMachine()) { 172 case llvm::Triple::aarch64: 173 reg_interface = new RegisterInfoPOSIX_arm64(arch); 174 break; 175 case llvm::Triple::arm: 176 reg_interface = new RegisterInfoPOSIX_arm(arch); 177 break; 178 case llvm::Triple::x86: 179 reg_interface = new RegisterContextOpenBSD_i386(arch); 180 break; 181 case llvm::Triple::x86_64: 182 reg_interface = new RegisterContextOpenBSD_x86_64(arch); 183 break; 184 default: 185 break; 186 } 187 break; 188 } 189 190 default: 191 break; 192 } 193 194 if (!reg_interface) { 195 if (log) 196 log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported", 197 __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); 198 assert(false && "Architecture or OS not supported"); 199 } 200 201 switch (arch.GetMachine()) { 202 case llvm::Triple::aarch64: 203 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64( 204 *this, reg_interface, m_gpregset_data, m_notes)); 205 break; 206 case llvm::Triple::arm: 207 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm( 208 *this, reg_interface, m_gpregset_data, m_notes)); 209 break; 210 case llvm::Triple::mipsel: 211 case llvm::Triple::mips: 212 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64( 213 *this, reg_interface, m_gpregset_data, m_notes)); 214 break; 215 case llvm::Triple::mips64: 216 case llvm::Triple::mips64el: 217 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64( 218 *this, reg_interface, m_gpregset_data, m_notes)); 219 break; 220 case llvm::Triple::ppc: 221 case llvm::Triple::ppc64: 222 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc( 223 *this, reg_interface, m_gpregset_data, m_notes)); 224 break; 225 case llvm::Triple::ppc64le: 226 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_ppc64le( 227 *this, reg_interface, m_gpregset_data, m_notes)); 228 break; 229#ifdef LLDB_ENABLE_ALL 230 case llvm::Triple::systemz: 231 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x( 232 *this, reg_interface, m_gpregset_data, m_notes)); 233 break; 234#endif // LLDB_ENABLE_ALL 235 case llvm::Triple::x86: 236 case llvm::Triple::x86_64: 237 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64( 238 *this, reg_interface, m_gpregset_data, m_notes)); 239 break; 240 default: 241 break; 242 } 243 244 reg_ctx_sp = m_thread_reg_ctx_sp; 245 } else if (m_unwinder_ap.get()) { 246 reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame); 247 } 248 return reg_ctx_sp; 249} 250 251bool ThreadElfCore::CalculateStopInfo() { 252 ProcessSP process_sp(GetProcess()); 253 if (process_sp) { 254 SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo)); 255 return true; 256 } 257 return false; 258} 259 260//---------------------------------------------------------------- 261// Parse PRSTATUS from NOTE entry 262//---------------------------------------------------------------- 263ELFLinuxPrStatus::ELFLinuxPrStatus() { 264 memset(this, 0, sizeof(ELFLinuxPrStatus)); 265} 266 267size_t ELFLinuxPrStatus::GetSize(const lldb_private::ArchSpec &arch) { 268 constexpr size_t mips_linux_pr_status_size_o32 = 96; 269 constexpr size_t mips_linux_pr_status_size_n32 = 72; 270 if (arch.IsMIPS()) { 271 std::string abi = arch.GetTargetABI(); 272 assert(!abi.empty() && "ABI is not set"); 273 if (!abi.compare("n64")) 274 return sizeof(ELFLinuxPrStatus); 275 else if (!abi.compare("o32")) 276 return mips_linux_pr_status_size_o32; 277 // N32 ABI 278 return mips_linux_pr_status_size_n32; 279 } 280 switch (arch.GetCore()) { 281 case lldb_private::ArchSpec::eCore_s390x_generic: 282 case lldb_private::ArchSpec::eCore_x86_64_x86_64: 283 case lldb_private::ArchSpec::eCore_ppc64le_generic: 284 return sizeof(ELFLinuxPrStatus); 285 case lldb_private::ArchSpec::eCore_x86_32_i386: 286 case lldb_private::ArchSpec::eCore_x86_32_i486: 287 return 72; 288 default: 289 return 0; 290 } 291} 292 293Status ELFLinuxPrStatus::Parse(const DataExtractor &data, 294 const ArchSpec &arch) { 295 Status error; 296 if (GetSize(arch) > data.GetByteSize()) { 297 error.SetErrorStringWithFormat( 298 "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64, 299 GetSize(arch), data.GetByteSize()); 300 return error; 301 } 302 303 // Read field by field to correctly account for endianess 304 // of both the core dump and the platform running lldb. 305 offset_t offset = 0; 306 si_signo = data.GetU32(&offset); 307 si_code = data.GetU32(&offset); 308 si_errno = data.GetU32(&offset); 309 310 pr_cursig = data.GetU16(&offset); 311 offset += 2; // pad 312 313 pr_sigpend = data.GetPointer(&offset); 314 pr_sighold = data.GetPointer(&offset); 315 316 pr_pid = data.GetU32(&offset); 317 pr_ppid = data.GetU32(&offset); 318 pr_pgrp = data.GetU32(&offset); 319 pr_sid = data.GetU32(&offset); 320 321 pr_utime.tv_sec = data.GetPointer(&offset); 322 pr_utime.tv_usec = data.GetPointer(&offset); 323 324 pr_stime.tv_sec = data.GetPointer(&offset); 325 pr_stime.tv_usec = data.GetPointer(&offset); 326 327 pr_cutime.tv_sec = data.GetPointer(&offset); 328 pr_cutime.tv_usec = data.GetPointer(&offset); 329 330 pr_cstime.tv_sec = data.GetPointer(&offset); 331 pr_cstime.tv_usec = data.GetPointer(&offset); 332 333 return error; 334} 335 336//---------------------------------------------------------------- 337// Parse PRPSINFO from NOTE entry 338//---------------------------------------------------------------- 339ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { 340 memset(this, 0, sizeof(ELFLinuxPrPsInfo)); 341} 342 343size_t ELFLinuxPrPsInfo::GetSize(const lldb_private::ArchSpec &arch) { 344 constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128; 345 if (arch.IsMIPS()) { 346 uint8_t address_byte_size = arch.GetAddressByteSize(); 347 if (address_byte_size == 8) 348 return sizeof(ELFLinuxPrPsInfo); 349 return mips_linux_pr_psinfo_size_o32_n32; 350 } 351 352 switch (arch.GetCore()) { 353 case lldb_private::ArchSpec::eCore_s390x_generic: 354 case lldb_private::ArchSpec::eCore_x86_64_x86_64: 355 return sizeof(ELFLinuxPrPsInfo); 356 case lldb_private::ArchSpec::eCore_x86_32_i386: 357 case lldb_private::ArchSpec::eCore_x86_32_i486: 358 return 124; 359 default: 360 return 0; 361 } 362} 363 364Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, 365 const ArchSpec &arch) { 366 Status error; 367 ByteOrder byteorder = data.GetByteOrder(); 368 if (GetSize(arch) > data.GetByteSize()) { 369 error.SetErrorStringWithFormat( 370 "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64, 371 GetSize(arch), data.GetByteSize()); 372 return error; 373 } 374 size_t size = 0; 375 offset_t offset = 0; 376 377 pr_state = data.GetU8(&offset); 378 pr_sname = data.GetU8(&offset); 379 pr_zomb = data.GetU8(&offset); 380 pr_nice = data.GetU8(&offset); 381 if (data.GetAddressByteSize() == 8) { 382 // Word align the next field on 64 bit. 383 offset += 4; 384 } 385 386 pr_flag = data.GetPointer(&offset); 387 388 if (arch.IsMIPS()) { 389 // The pr_uid and pr_gid is always 32 bit irrespective of platforms 390 pr_uid = data.GetU32(&offset); 391 pr_gid = data.GetU32(&offset); 392 } else { 393 // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms 394 pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); 395 pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); 396 } 397 398 pr_pid = data.GetU32(&offset); 399 pr_ppid = data.GetU32(&offset); 400 pr_pgrp = data.GetU32(&offset); 401 pr_sid = data.GetU32(&offset); 402 403 size = 16; 404 data.ExtractBytes(offset, size, byteorder, pr_fname); 405 offset += size; 406 407 size = 80; 408 data.ExtractBytes(offset, size, byteorder, pr_psargs); 409 offset += size; 410 411 return error; 412} 413 414//---------------------------------------------------------------- 415// Parse SIGINFO from NOTE entry 416//---------------------------------------------------------------- 417ELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); } 418 419size_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) { 420 if (arch.IsMIPS()) 421 return sizeof(ELFLinuxSigInfo); 422 switch (arch.GetCore()) { 423 case lldb_private::ArchSpec::eCore_x86_64_x86_64: 424 return sizeof(ELFLinuxSigInfo); 425 case lldb_private::ArchSpec::eCore_s390x_generic: 426 case lldb_private::ArchSpec::eCore_x86_32_i386: 427 case lldb_private::ArchSpec::eCore_x86_32_i486: 428 return 12; 429 default: 430 return 0; 431 } 432} 433 434Status ELFLinuxSigInfo::Parse(const DataExtractor &data, const ArchSpec &arch) { 435 Status error; 436 if (GetSize(arch) > data.GetByteSize()) { 437 error.SetErrorStringWithFormat( 438 "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64, 439 GetSize(arch), data.GetByteSize()); 440 return error; 441 } 442 443 // Parsing from a 32 bit ELF core file, and populating/reusing the structure 444 // properly, because the struct is for the 64 bit version 445 offset_t offset = 0; 446 si_signo = data.GetU32(&offset); 447 si_code = data.GetU32(&offset); 448 si_errno = data.GetU32(&offset); 449 450 return error; 451} 452