ThreadElfCore.cpp revision 353358
1254721Semaste//===-- ThreadElfCore.cpp --------------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#include "lldb/Target/RegisterContext.h" 10254721Semaste#include "lldb/Target/StopInfo.h" 11254721Semaste#include "lldb/Target/Target.h" 12254721Semaste#include "lldb/Target/Unwind.h" 13321369Sdim#include "lldb/Utility/DataExtractor.h" 14321369Sdim#include "lldb/Utility/Log.h" 15254721Semaste 16280031Sdim#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" 17280031Sdim#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" 18280031Sdim#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" 19280031Sdim#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" 20327952Sdim#include "Plugins/Process/Utility/RegisterContextLinux_i386.h" 21327952Sdim#include "Plugins/Process/Utility/RegisterContextLinux_mips.h" 22321369Sdim#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h" 23327952Sdim#ifdef LLDB_ENABLE_ALL 24327952Sdim#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h" 25327952Sdim#endif // LLDB_ENABLE_ALL 26314564Sdim#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" 27321369Sdim#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" 28321369Sdim#include "Plugins/Process/Utility/RegisterContextOpenBSD_i386.h" 29321369Sdim#include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h" 30321369Sdim#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h" 31314564Sdim#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" 32327952Sdim#include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h" 33314564Sdim#include "ProcessElfCore.h" 34288943Sdim#include "RegisterContextPOSIXCore_arm.h" 35288943Sdim#include "RegisterContextPOSIXCore_arm64.h" 36258054Semaste#include "RegisterContextPOSIXCore_mips64.h" 37280031Sdim#include "RegisterContextPOSIXCore_powerpc.h" 38327952Sdim#include "RegisterContextPOSIXCore_ppc64le.h" 39327952Sdim#ifdef LLDB_ENABLE_ALL 40327952Sdim#include "RegisterContextPOSIXCore_s390x.h" 41327952Sdim#endif // LLDB_ENABLE_ALL 42258054Semaste#include "RegisterContextPOSIXCore_x86_64.h" 43314564Sdim#include "ThreadElfCore.h" 44254721Semaste 45353358Sdim#include <memory> 46353358Sdim 47254721Semasteusing namespace lldb; 48254721Semasteusing namespace lldb_private; 49254721Semaste 50254721Semaste// Construct a Thread object with given data 51314564SdimThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td) 52314564Sdim : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(), 53327952Sdim m_signo(td.signo), m_gpregset_data(td.gpregset), m_notes(td.notes) {} 54254721Semaste 55314564SdimThreadElfCore::~ThreadElfCore() { DestroyThread(); } 56254721Semaste 57314564Sdimvoid ThreadElfCore::RefreshStateAfterStop() { 58314564Sdim GetRegisterContext()->InvalidateIfNeeded(false); 59254721Semaste} 60254721Semaste 61314564SdimRegisterContextSP ThreadElfCore::GetRegisterContext() { 62341825Sdim if (!m_reg_context_sp) { 63341825Sdim m_reg_context_sp = CreateRegisterContextForFrame(nullptr); 64314564Sdim } 65314564Sdim return m_reg_context_sp; 66254721Semaste} 67254721Semaste 68254721SemasteRegisterContextSP 69314564SdimThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { 70314564Sdim RegisterContextSP reg_ctx_sp; 71314564Sdim uint32_t concrete_frame_idx = 0; 72314564Sdim Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); 73254721Semaste 74314564Sdim if (frame) 75314564Sdim concrete_frame_idx = frame->GetConcreteFrameIndex(); 76254721Semaste 77314564Sdim if (concrete_frame_idx == 0) { 78314564Sdim if (m_thread_reg_ctx_sp) 79314564Sdim return m_thread_reg_ctx_sp; 80254721Semaste 81314564Sdim ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get()); 82314564Sdim ArchSpec arch = process->GetArchitecture(); 83341825Sdim RegisterInfoInterface *reg_interface = nullptr; 84262528Semaste 85314564Sdim switch (arch.GetTriple().getOS()) { 86314564Sdim case llvm::Triple::FreeBSD: { 87314564Sdim switch (arch.GetMachine()) { 88314564Sdim case llvm::Triple::aarch64: 89314564Sdim reg_interface = new RegisterInfoPOSIX_arm64(arch); 90314564Sdim break; 91314564Sdim case llvm::Triple::arm: 92321369Sdim reg_interface = new RegisterInfoPOSIX_arm(arch); 93314564Sdim break; 94314564Sdim case llvm::Triple::ppc: 95314564Sdim reg_interface = new RegisterContextFreeBSD_powerpc32(arch); 96314564Sdim break; 97314564Sdim case llvm::Triple::ppc64: 98314564Sdim reg_interface = new RegisterContextFreeBSD_powerpc64(arch); 99314564Sdim break; 100314564Sdim case llvm::Triple::mips64: 101314564Sdim reg_interface = new RegisterContextFreeBSD_mips64(arch); 102314564Sdim break; 103314564Sdim case llvm::Triple::x86: 104314564Sdim reg_interface = new RegisterContextFreeBSD_i386(arch); 105314564Sdim break; 106314564Sdim case llvm::Triple::x86_64: 107314564Sdim reg_interface = new RegisterContextFreeBSD_x86_64(arch); 108314564Sdim break; 109314564Sdim default: 110314564Sdim break; 111314564Sdim } 112314564Sdim break; 113314564Sdim } 114276479Sdim 115321369Sdim case llvm::Triple::NetBSD: { 116321369Sdim switch (arch.GetMachine()) { 117353358Sdim case llvm::Triple::aarch64: 118353358Sdim reg_interface = new RegisterInfoPOSIX_arm64(arch); 119353358Sdim break; 120321369Sdim case llvm::Triple::x86_64: 121321369Sdim reg_interface = new RegisterContextNetBSD_x86_64(arch); 122321369Sdim break; 123321369Sdim default: 124321369Sdim break; 125321369Sdim } 126321369Sdim break; 127321369Sdim } 128321369Sdim 129314564Sdim case llvm::Triple::Linux: { 130314564Sdim switch (arch.GetMachine()) { 131314564Sdim case llvm::Triple::arm: 132321369Sdim reg_interface = new RegisterInfoPOSIX_arm(arch); 133314564Sdim break; 134314564Sdim case llvm::Triple::aarch64: 135314564Sdim reg_interface = new RegisterInfoPOSIX_arm64(arch); 136314564Sdim break; 137321369Sdim case llvm::Triple::mipsel: 138321369Sdim case llvm::Triple::mips: 139321369Sdim reg_interface = new RegisterContextLinux_mips(arch); 140321369Sdim break; 141321369Sdim case llvm::Triple::mips64el: 142321369Sdim case llvm::Triple::mips64: 143321369Sdim reg_interface = new RegisterContextLinux_mips64(arch); 144321369Sdim break; 145327952Sdim case llvm::Triple::ppc64le: 146327952Sdim reg_interface = new RegisterInfoPOSIX_ppc64le(arch); 147327952Sdim break; 148327952Sdim#ifdef LLDB_ENABLE_ALL 149327952Sdim case llvm::Triple::systemz: 150327952Sdim reg_interface = new RegisterContextLinux_s390x(arch); 151327952Sdim break; 152327952Sdim#endif // LLDB_ENABLE_ALL 153314564Sdim case llvm::Triple::x86: 154314564Sdim reg_interface = new RegisterContextLinux_i386(arch); 155314564Sdim break; 156314564Sdim case llvm::Triple::x86_64: 157314564Sdim reg_interface = new RegisterContextLinux_x86_64(arch); 158314564Sdim break; 159314564Sdim default: 160314564Sdim break; 161314564Sdim } 162314564Sdim break; 163314564Sdim } 164262528Semaste 165321369Sdim case llvm::Triple::OpenBSD: { 166321369Sdim switch (arch.GetMachine()) { 167321369Sdim case llvm::Triple::aarch64: 168321369Sdim reg_interface = new RegisterInfoPOSIX_arm64(arch); 169321369Sdim break; 170321369Sdim case llvm::Triple::arm: 171321369Sdim reg_interface = new RegisterInfoPOSIX_arm(arch); 172321369Sdim break; 173321369Sdim case llvm::Triple::x86: 174321369Sdim reg_interface = new RegisterContextOpenBSD_i386(arch); 175321369Sdim break; 176321369Sdim case llvm::Triple::x86_64: 177321369Sdim reg_interface = new RegisterContextOpenBSD_x86_64(arch); 178321369Sdim break; 179321369Sdim default: 180321369Sdim break; 181321369Sdim } 182321369Sdim break; 183321369Sdim } 184321369Sdim 185314564Sdim default: 186314564Sdim break; 187314564Sdim } 188262528Semaste 189314564Sdim if (!reg_interface) { 190314564Sdim if (log) 191314564Sdim log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported", 192314564Sdim __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); 193314564Sdim assert(false && "Architecture or OS not supported"); 194314564Sdim } 195262528Semaste 196314564Sdim switch (arch.GetMachine()) { 197314564Sdim case llvm::Triple::aarch64: 198353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm64>( 199353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 200314564Sdim break; 201314564Sdim case llvm::Triple::arm: 202353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm>( 203353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 204314564Sdim break; 205321369Sdim case llvm::Triple::mipsel: 206321369Sdim case llvm::Triple::mips: 207353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_mips64>( 208353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 209321369Sdim break; 210314564Sdim case llvm::Triple::mips64: 211321369Sdim case llvm::Triple::mips64el: 212353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_mips64>( 213353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 214314564Sdim break; 215314564Sdim case llvm::Triple::ppc: 216314564Sdim case llvm::Triple::ppc64: 217353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_powerpc>( 218353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 219314564Sdim break; 220327952Sdim case llvm::Triple::ppc64le: 221353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_ppc64le>( 222353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 223327952Sdim break; 224327952Sdim#ifdef LLDB_ENABLE_ALL 225327952Sdim case llvm::Triple::systemz: 226353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_s390x>( 227353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 228327952Sdim break; 229327952Sdim#endif // LLDB_ENABLE_ALL 230314564Sdim case llvm::Triple::x86: 231314564Sdim case llvm::Triple::x86_64: 232353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>( 233353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 234314564Sdim break; 235314564Sdim default: 236314564Sdim break; 237314564Sdim } 238262528Semaste 239314564Sdim reg_ctx_sp = m_thread_reg_ctx_sp; 240341825Sdim } else { 241341825Sdim Unwind *unwinder = GetUnwinder(); 242341825Sdim if (unwinder != nullptr) 243341825Sdim reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); 244314564Sdim } 245314564Sdim return reg_ctx_sp; 246254721Semaste} 247254721Semaste 248314564Sdimbool ThreadElfCore::CalculateStopInfo() { 249314564Sdim ProcessSP process_sp(GetProcess()); 250314564Sdim if (process_sp) { 251314564Sdim SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo)); 252314564Sdim return true; 253314564Sdim } 254314564Sdim return false; 255254721Semaste} 256254721Semaste 257254721Semaste// Parse PRSTATUS from NOTE entry 258314564SdimELFLinuxPrStatus::ELFLinuxPrStatus() { 259314564Sdim memset(this, 0, sizeof(ELFLinuxPrStatus)); 260254721Semaste} 261254721Semaste 262327952Sdimsize_t ELFLinuxPrStatus::GetSize(const lldb_private::ArchSpec &arch) { 263321369Sdim constexpr size_t mips_linux_pr_status_size_o32 = 96; 264321369Sdim constexpr size_t mips_linux_pr_status_size_n32 = 72; 265353358Sdim constexpr size_t num_ptr_size_members = 10; 266321369Sdim if (arch.IsMIPS()) { 267321369Sdim std::string abi = arch.GetTargetABI(); 268321369Sdim assert(!abi.empty() && "ABI is not set"); 269321369Sdim if (!abi.compare("n64")) 270321369Sdim return sizeof(ELFLinuxPrStatus); 271321369Sdim else if (!abi.compare("o32")) 272321369Sdim return mips_linux_pr_status_size_o32; 273321369Sdim // N32 ABI 274321369Sdim return mips_linux_pr_status_size_n32; 275321369Sdim } 276321369Sdim switch (arch.GetCore()) { 277321369Sdim case lldb_private::ArchSpec::eCore_x86_32_i386: 278321369Sdim case lldb_private::ArchSpec::eCore_x86_32_i486: 279321369Sdim return 72; 280321369Sdim default: 281353358Sdim if (arch.GetAddressByteSize() == 8) 282353358Sdim return sizeof(ELFLinuxPrStatus); 283353358Sdim else 284353358Sdim return sizeof(ELFLinuxPrStatus) - num_ptr_size_members * 4; 285321369Sdim } 286321369Sdim} 287321369Sdim 288327952SdimStatus ELFLinuxPrStatus::Parse(const DataExtractor &data, 289327952Sdim const ArchSpec &arch) { 290321369Sdim Status error; 291314564Sdim if (GetSize(arch) > data.GetByteSize()) { 292314564Sdim error.SetErrorStringWithFormat( 293314564Sdim "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64, 294314564Sdim GetSize(arch), data.GetByteSize()); 295314564Sdim return error; 296314564Sdim } 297314564Sdim 298341825Sdim // Read field by field to correctly account for endianess of both the core 299341825Sdim // dump and the platform running lldb. 300314564Sdim offset_t offset = 0; 301314564Sdim si_signo = data.GetU32(&offset); 302314564Sdim si_code = data.GetU32(&offset); 303314564Sdim si_errno = data.GetU32(&offset); 304314564Sdim 305314564Sdim pr_cursig = data.GetU16(&offset); 306314564Sdim offset += 2; // pad 307314564Sdim 308314564Sdim pr_sigpend = data.GetPointer(&offset); 309314564Sdim pr_sighold = data.GetPointer(&offset); 310314564Sdim 311314564Sdim pr_pid = data.GetU32(&offset); 312314564Sdim pr_ppid = data.GetU32(&offset); 313314564Sdim pr_pgrp = data.GetU32(&offset); 314314564Sdim pr_sid = data.GetU32(&offset); 315314564Sdim 316314564Sdim pr_utime.tv_sec = data.GetPointer(&offset); 317314564Sdim pr_utime.tv_usec = data.GetPointer(&offset); 318314564Sdim 319314564Sdim pr_stime.tv_sec = data.GetPointer(&offset); 320314564Sdim pr_stime.tv_usec = data.GetPointer(&offset); 321314564Sdim 322314564Sdim pr_cutime.tv_sec = data.GetPointer(&offset); 323314564Sdim pr_cutime.tv_usec = data.GetPointer(&offset); 324314564Sdim 325314564Sdim pr_cstime.tv_sec = data.GetPointer(&offset); 326314564Sdim pr_cstime.tv_usec = data.GetPointer(&offset); 327314564Sdim 328314564Sdim return error; 329254721Semaste} 330254721Semaste 331254721Semaste// Parse PRPSINFO from NOTE entry 332314564SdimELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { 333314564Sdim memset(this, 0, sizeof(ELFLinuxPrPsInfo)); 334254721Semaste} 335254721Semaste 336327952Sdimsize_t ELFLinuxPrPsInfo::GetSize(const lldb_private::ArchSpec &arch) { 337321369Sdim constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128; 338321369Sdim if (arch.IsMIPS()) { 339321369Sdim uint8_t address_byte_size = arch.GetAddressByteSize(); 340321369Sdim if (address_byte_size == 8) 341321369Sdim return sizeof(ELFLinuxPrPsInfo); 342321369Sdim return mips_linux_pr_psinfo_size_o32_n32; 343321369Sdim } 344341825Sdim 345321369Sdim switch (arch.GetCore()) { 346321369Sdim case lldb_private::ArchSpec::eCore_s390x_generic: 347321369Sdim case lldb_private::ArchSpec::eCore_x86_64_x86_64: 348321369Sdim return sizeof(ELFLinuxPrPsInfo); 349321369Sdim case lldb_private::ArchSpec::eCore_x86_32_i386: 350321369Sdim case lldb_private::ArchSpec::eCore_x86_32_i486: 351321369Sdim return 124; 352321369Sdim default: 353321369Sdim return 0; 354321369Sdim } 355321369Sdim} 356321369Sdim 357327952SdimStatus ELFLinuxPrPsInfo::Parse(const DataExtractor &data, 358327952Sdim const ArchSpec &arch) { 359321369Sdim Status error; 360314564Sdim ByteOrder byteorder = data.GetByteOrder(); 361314564Sdim if (GetSize(arch) > data.GetByteSize()) { 362314564Sdim error.SetErrorStringWithFormat( 363314564Sdim "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64, 364314564Sdim GetSize(arch), data.GetByteSize()); 365314564Sdim return error; 366314564Sdim } 367314564Sdim size_t size = 0; 368314564Sdim offset_t offset = 0; 369314564Sdim 370314564Sdim pr_state = data.GetU8(&offset); 371314564Sdim pr_sname = data.GetU8(&offset); 372314564Sdim pr_zomb = data.GetU8(&offset); 373314564Sdim pr_nice = data.GetU8(&offset); 374314564Sdim if (data.GetAddressByteSize() == 8) { 375314564Sdim // Word align the next field on 64 bit. 376314564Sdim offset += 4; 377314564Sdim } 378314564Sdim 379314564Sdim pr_flag = data.GetPointer(&offset); 380314564Sdim 381321369Sdim if (arch.IsMIPS()) { 382321369Sdim // The pr_uid and pr_gid is always 32 bit irrespective of platforms 383321369Sdim pr_uid = data.GetU32(&offset); 384321369Sdim pr_gid = data.GetU32(&offset); 385321369Sdim } else { 386341825Sdim // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms 387341825Sdim pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); 388341825Sdim pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); 389321369Sdim } 390314564Sdim 391314564Sdim pr_pid = data.GetU32(&offset); 392314564Sdim pr_ppid = data.GetU32(&offset); 393314564Sdim pr_pgrp = data.GetU32(&offset); 394314564Sdim pr_sid = data.GetU32(&offset); 395314564Sdim 396314564Sdim size = 16; 397314564Sdim data.ExtractBytes(offset, size, byteorder, pr_fname); 398314564Sdim offset += size; 399314564Sdim 400314564Sdim size = 80; 401314564Sdim data.ExtractBytes(offset, size, byteorder, pr_psargs); 402314564Sdim offset += size; 403314564Sdim 404314564Sdim return error; 405254721Semaste} 406254721Semaste 407314564Sdim// Parse SIGINFO from NOTE entry 408321369SdimELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); } 409321369Sdim 410321369Sdimsize_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) { 411321369Sdim if (arch.IsMIPS()) 412321369Sdim return sizeof(ELFLinuxSigInfo); 413321369Sdim switch (arch.GetCore()) { 414321369Sdim case lldb_private::ArchSpec::eCore_x86_64_x86_64: 415321369Sdim return sizeof(ELFLinuxSigInfo); 416321369Sdim case lldb_private::ArchSpec::eCore_s390x_generic: 417321369Sdim case lldb_private::ArchSpec::eCore_x86_32_i386: 418321369Sdim case lldb_private::ArchSpec::eCore_x86_32_i486: 419321369Sdim return 12; 420321369Sdim default: 421321369Sdim return 0; 422321369Sdim } 423314564Sdim} 424314564Sdim 425327952SdimStatus ELFLinuxSigInfo::Parse(const DataExtractor &data, const ArchSpec &arch) { 426321369Sdim Status error; 427314564Sdim if (GetSize(arch) > data.GetByteSize()) { 428314564Sdim error.SetErrorStringWithFormat( 429314564Sdim "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64, 430314564Sdim GetSize(arch), data.GetByteSize()); 431314564Sdim return error; 432314564Sdim } 433314564Sdim 434314564Sdim // Parsing from a 32 bit ELF core file, and populating/reusing the structure 435314564Sdim // properly, because the struct is for the 64 bit version 436314564Sdim offset_t offset = 0; 437314564Sdim si_signo = data.GetU32(&offset); 438314564Sdim si_code = data.GetU32(&offset); 439314564Sdim si_errno = data.GetU32(&offset); 440314564Sdim 441314564Sdim return error; 442314564Sdim} 443