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) { 190360784Sdim LLDB_LOGF(log, "elf-core::%s:: Architecture(%d) or OS(%d) not supported", 191360784Sdim __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); 192314564Sdim assert(false && "Architecture or OS not supported"); 193314564Sdim } 194262528Semaste 195314564Sdim switch (arch.GetMachine()) { 196314564Sdim case llvm::Triple::aarch64: 197353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm64>( 198353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 199314564Sdim break; 200314564Sdim case llvm::Triple::arm: 201353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm>( 202353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 203314564Sdim break; 204321369Sdim case llvm::Triple::mipsel: 205321369Sdim case llvm::Triple::mips: 206353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_mips64>( 207353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 208321369Sdim break; 209314564Sdim case llvm::Triple::mips64: 210321369Sdim case llvm::Triple::mips64el: 211353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_mips64>( 212353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 213314564Sdim break; 214314564Sdim case llvm::Triple::ppc: 215314564Sdim case llvm::Triple::ppc64: 216353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_powerpc>( 217353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 218314564Sdim break; 219327952Sdim case llvm::Triple::ppc64le: 220353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_ppc64le>( 221353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 222327952Sdim break; 223327952Sdim#ifdef LLDB_ENABLE_ALL 224327952Sdim case llvm::Triple::systemz: 225353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_s390x>( 226353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 227327952Sdim break; 228327952Sdim#endif // LLDB_ENABLE_ALL 229314564Sdim case llvm::Triple::x86: 230314564Sdim case llvm::Triple::x86_64: 231353358Sdim m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>( 232353358Sdim *this, reg_interface, m_gpregset_data, m_notes); 233314564Sdim break; 234314564Sdim default: 235314564Sdim break; 236314564Sdim } 237262528Semaste 238314564Sdim reg_ctx_sp = m_thread_reg_ctx_sp; 239341825Sdim } else { 240341825Sdim Unwind *unwinder = GetUnwinder(); 241341825Sdim if (unwinder != nullptr) 242341825Sdim reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); 243314564Sdim } 244314564Sdim return reg_ctx_sp; 245254721Semaste} 246254721Semaste 247314564Sdimbool ThreadElfCore::CalculateStopInfo() { 248314564Sdim ProcessSP process_sp(GetProcess()); 249314564Sdim if (process_sp) { 250314564Sdim SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo)); 251314564Sdim return true; 252314564Sdim } 253314564Sdim return false; 254254721Semaste} 255254721Semaste 256254721Semaste// Parse PRSTATUS from NOTE entry 257314564SdimELFLinuxPrStatus::ELFLinuxPrStatus() { 258314564Sdim memset(this, 0, sizeof(ELFLinuxPrStatus)); 259254721Semaste} 260254721Semaste 261327952Sdimsize_t ELFLinuxPrStatus::GetSize(const lldb_private::ArchSpec &arch) { 262321369Sdim constexpr size_t mips_linux_pr_status_size_o32 = 96; 263321369Sdim constexpr size_t mips_linux_pr_status_size_n32 = 72; 264353358Sdim constexpr size_t num_ptr_size_members = 10; 265321369Sdim if (arch.IsMIPS()) { 266321369Sdim std::string abi = arch.GetTargetABI(); 267321369Sdim assert(!abi.empty() && "ABI is not set"); 268321369Sdim if (!abi.compare("n64")) 269321369Sdim return sizeof(ELFLinuxPrStatus); 270321369Sdim else if (!abi.compare("o32")) 271321369Sdim return mips_linux_pr_status_size_o32; 272321369Sdim // N32 ABI 273321369Sdim return mips_linux_pr_status_size_n32; 274321369Sdim } 275321369Sdim switch (arch.GetCore()) { 276321369Sdim case lldb_private::ArchSpec::eCore_x86_32_i386: 277321369Sdim case lldb_private::ArchSpec::eCore_x86_32_i486: 278321369Sdim return 72; 279321369Sdim default: 280353358Sdim if (arch.GetAddressByteSize() == 8) 281353358Sdim return sizeof(ELFLinuxPrStatus); 282353358Sdim else 283353358Sdim return sizeof(ELFLinuxPrStatus) - num_ptr_size_members * 4; 284321369Sdim } 285321369Sdim} 286321369Sdim 287327952SdimStatus ELFLinuxPrStatus::Parse(const DataExtractor &data, 288327952Sdim const ArchSpec &arch) { 289321369Sdim Status error; 290314564Sdim if (GetSize(arch) > data.GetByteSize()) { 291314564Sdim error.SetErrorStringWithFormat( 292314564Sdim "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64, 293314564Sdim GetSize(arch), data.GetByteSize()); 294314564Sdim return error; 295314564Sdim } 296314564Sdim 297341825Sdim // Read field by field to correctly account for endianess of both the core 298341825Sdim // dump and the platform running lldb. 299314564Sdim offset_t offset = 0; 300314564Sdim si_signo = data.GetU32(&offset); 301314564Sdim si_code = data.GetU32(&offset); 302314564Sdim si_errno = data.GetU32(&offset); 303314564Sdim 304314564Sdim pr_cursig = data.GetU16(&offset); 305314564Sdim offset += 2; // pad 306314564Sdim 307314564Sdim pr_sigpend = data.GetPointer(&offset); 308314564Sdim pr_sighold = data.GetPointer(&offset); 309314564Sdim 310314564Sdim pr_pid = data.GetU32(&offset); 311314564Sdim pr_ppid = data.GetU32(&offset); 312314564Sdim pr_pgrp = data.GetU32(&offset); 313314564Sdim pr_sid = data.GetU32(&offset); 314314564Sdim 315314564Sdim pr_utime.tv_sec = data.GetPointer(&offset); 316314564Sdim pr_utime.tv_usec = data.GetPointer(&offset); 317314564Sdim 318314564Sdim pr_stime.tv_sec = data.GetPointer(&offset); 319314564Sdim pr_stime.tv_usec = data.GetPointer(&offset); 320314564Sdim 321314564Sdim pr_cutime.tv_sec = data.GetPointer(&offset); 322314564Sdim pr_cutime.tv_usec = data.GetPointer(&offset); 323314564Sdim 324314564Sdim pr_cstime.tv_sec = data.GetPointer(&offset); 325314564Sdim pr_cstime.tv_usec = data.GetPointer(&offset); 326314564Sdim 327314564Sdim return error; 328254721Semaste} 329254721Semaste 330254721Semaste// Parse PRPSINFO from NOTE entry 331314564SdimELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { 332314564Sdim memset(this, 0, sizeof(ELFLinuxPrPsInfo)); 333254721Semaste} 334254721Semaste 335327952Sdimsize_t ELFLinuxPrPsInfo::GetSize(const lldb_private::ArchSpec &arch) { 336321369Sdim constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128; 337321369Sdim if (arch.IsMIPS()) { 338321369Sdim uint8_t address_byte_size = arch.GetAddressByteSize(); 339321369Sdim if (address_byte_size == 8) 340321369Sdim return sizeof(ELFLinuxPrPsInfo); 341321369Sdim return mips_linux_pr_psinfo_size_o32_n32; 342321369Sdim } 343341825Sdim 344321369Sdim switch (arch.GetCore()) { 345321369Sdim case lldb_private::ArchSpec::eCore_s390x_generic: 346321369Sdim case lldb_private::ArchSpec::eCore_x86_64_x86_64: 347321369Sdim return sizeof(ELFLinuxPrPsInfo); 348321369Sdim case lldb_private::ArchSpec::eCore_x86_32_i386: 349321369Sdim case lldb_private::ArchSpec::eCore_x86_32_i486: 350321369Sdim return 124; 351321369Sdim default: 352321369Sdim return 0; 353321369Sdim } 354321369Sdim} 355321369Sdim 356327952SdimStatus ELFLinuxPrPsInfo::Parse(const DataExtractor &data, 357327952Sdim const ArchSpec &arch) { 358321369Sdim Status error; 359314564Sdim ByteOrder byteorder = data.GetByteOrder(); 360314564Sdim if (GetSize(arch) > data.GetByteSize()) { 361314564Sdim error.SetErrorStringWithFormat( 362314564Sdim "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64, 363314564Sdim GetSize(arch), data.GetByteSize()); 364314564Sdim return error; 365314564Sdim } 366314564Sdim size_t size = 0; 367314564Sdim offset_t offset = 0; 368314564Sdim 369314564Sdim pr_state = data.GetU8(&offset); 370314564Sdim pr_sname = data.GetU8(&offset); 371314564Sdim pr_zomb = data.GetU8(&offset); 372314564Sdim pr_nice = data.GetU8(&offset); 373314564Sdim if (data.GetAddressByteSize() == 8) { 374314564Sdim // Word align the next field on 64 bit. 375314564Sdim offset += 4; 376314564Sdim } 377314564Sdim 378314564Sdim pr_flag = data.GetPointer(&offset); 379314564Sdim 380321369Sdim if (arch.IsMIPS()) { 381321369Sdim // The pr_uid and pr_gid is always 32 bit irrespective of platforms 382321369Sdim pr_uid = data.GetU32(&offset); 383321369Sdim pr_gid = data.GetU32(&offset); 384321369Sdim } else { 385341825Sdim // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms 386341825Sdim pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); 387341825Sdim pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); 388321369Sdim } 389314564Sdim 390314564Sdim pr_pid = data.GetU32(&offset); 391314564Sdim pr_ppid = data.GetU32(&offset); 392314564Sdim pr_pgrp = data.GetU32(&offset); 393314564Sdim pr_sid = data.GetU32(&offset); 394314564Sdim 395314564Sdim size = 16; 396314564Sdim data.ExtractBytes(offset, size, byteorder, pr_fname); 397314564Sdim offset += size; 398314564Sdim 399314564Sdim size = 80; 400314564Sdim data.ExtractBytes(offset, size, byteorder, pr_psargs); 401314564Sdim offset += size; 402314564Sdim 403314564Sdim return error; 404254721Semaste} 405254721Semaste 406314564Sdim// Parse SIGINFO from NOTE entry 407321369SdimELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); } 408321369Sdim 409321369Sdimsize_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) { 410321369Sdim if (arch.IsMIPS()) 411321369Sdim return sizeof(ELFLinuxSigInfo); 412321369Sdim switch (arch.GetCore()) { 413321369Sdim case lldb_private::ArchSpec::eCore_x86_64_x86_64: 414321369Sdim return sizeof(ELFLinuxSigInfo); 415321369Sdim case lldb_private::ArchSpec::eCore_s390x_generic: 416321369Sdim case lldb_private::ArchSpec::eCore_x86_32_i386: 417321369Sdim case lldb_private::ArchSpec::eCore_x86_32_i486: 418321369Sdim return 12; 419321369Sdim default: 420321369Sdim return 0; 421321369Sdim } 422314564Sdim} 423314564Sdim 424327952SdimStatus ELFLinuxSigInfo::Parse(const DataExtractor &data, const ArchSpec &arch) { 425321369Sdim Status error; 426314564Sdim if (GetSize(arch) > data.GetByteSize()) { 427314564Sdim error.SetErrorStringWithFormat( 428314564Sdim "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64, 429314564Sdim GetSize(arch), data.GetByteSize()); 430314564Sdim return error; 431314564Sdim } 432314564Sdim 433314564Sdim // Parsing from a 32 bit ELF core file, and populating/reusing the structure 434314564Sdim // properly, because the struct is for the 64 bit version 435314564Sdim offset_t offset = 0; 436314564Sdim si_signo = data.GetU32(&offset); 437314564Sdim si_code = data.GetU32(&offset); 438314564Sdim si_errno = data.GetU32(&offset); 439314564Sdim 440314564Sdim return error; 441314564Sdim} 442