180 lines · c
1//===-- ThreadElfCore.h -----------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H10#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H11 12#include "Plugins/Process/elf-core/RegisterUtilities.h"13#include "lldb/Target/Platform.h"14#include "lldb/Target/Thread.h"15#include "lldb/Utility/DataExtractor.h"16#include "lldb/ValueObject/ValueObject.h"17#include "llvm/ADT/DenseMap.h"18#include <optional>19#include <string>20 21struct compat_timeval {22 alignas(8) uint64_t tv_sec;23 alignas(8) uint64_t tv_usec;24};25 26namespace lldb_private {27class ProcessInstanceInfo;28}29 30// PRSTATUS structure's size differs based on architecture.31// This is the layout in the x86-64 arch.32// In the i386 case we parse it manually and fill it again33// in the same structure34// The gp registers are also a part of this struct, but they are handled35// separately36 37#undef si_signo38#undef si_code39#undef si_errno40#undef si_addr41#undef si_addr_lsb42 43struct ELFLinuxPrStatus {44 int32_t si_signo;45 int32_t si_code;46 int32_t si_errno;47 48 int16_t pr_cursig;49 50 alignas(8) uint64_t pr_sigpend;51 alignas(8) uint64_t pr_sighold;52 53 uint32_t pr_pid;54 uint32_t pr_ppid;55 uint32_t pr_pgrp;56 uint32_t pr_sid;57 58 compat_timeval pr_utime;59 compat_timeval pr_stime;60 compat_timeval pr_cutime;61 compat_timeval pr_cstime;62 63 ELFLinuxPrStatus();64 65 lldb_private::Status Parse(const lldb_private::DataExtractor &data,66 const lldb_private::ArchSpec &arch);67 68 static std::optional<ELFLinuxPrStatus>69 Populate(const lldb::ThreadSP &thread_sp);70 71 // Return the bytesize of the structure72 // 64 bit - just sizeof73 // 32 bit - hardcoded because we are reusing the struct, but some of the74 // members are smaller -75 // so the layout is not the same76 static size_t GetSize(const lldb_private::ArchSpec &arch);77};78 79static_assert(sizeof(ELFLinuxPrStatus) == 112,80 "sizeof ELFLinuxPrStatus is not correct!");81 82struct ThreadData {83 lldb_private::DataExtractor gpregset;84 std::vector<lldb_private::CoreNote> notes;85 lldb::tid_t tid;86 std::string name;87 llvm::StringRef siginfo_bytes;88 int prstatus_sig = 0;89 int signo = 0;90};91 92// PRPSINFO structure's size differs based on architecture.93// This is the layout in the x86-64 arch case.94// In the i386 case we parse it manually and fill it again95// in the same structure96struct ELFLinuxPrPsInfo {97 char pr_state;98 char pr_sname;99 char pr_zomb;100 char pr_nice;101 alignas(8) uint64_t pr_flag;102 uint32_t pr_uid;103 uint32_t pr_gid;104 int32_t pr_pid;105 int32_t pr_ppid;106 int32_t pr_pgrp;107 int32_t pr_sid;108 char pr_fname[16];109 char pr_psargs[80];110 111 ELFLinuxPrPsInfo();112 113 lldb_private::Status Parse(const lldb_private::DataExtractor &data,114 const lldb_private::ArchSpec &arch);115 116 static std::optional<ELFLinuxPrPsInfo>117 Populate(const lldb::ProcessSP &process_sp);118 119 static std::optional<ELFLinuxPrPsInfo>120 Populate(const lldb_private::ProcessInstanceInfo &info,121 lldb::StateType state);122 123 // Return the bytesize of the structure124 // 64 bit - just sizeof125 // 32 bit - hardcoded because we are reusing the struct, but some of the126 // members are smaller -127 // so the layout is not the same128 static size_t GetSize(const lldb_private::ArchSpec &arch);129};130 131static_assert(sizeof(ELFLinuxPrPsInfo) == 136,132 "sizeof ELFLinuxPrPsInfo is not correct!");133 134class ThreadElfCore : public lldb_private::Thread {135public:136 ThreadElfCore(lldb_private::Process &process, const ThreadData &td);137 138 ~ThreadElfCore() override;139 140 void RefreshStateAfterStop() override;141 142 lldb::RegisterContextSP GetRegisterContext() override;143 144 lldb::RegisterContextSP145 CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;146 147 static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }148 149 const char *GetName() override {150 if (m_thread_name.empty())151 return nullptr;152 return m_thread_name.c_str();153 }154 155 void SetName(const char *name) override {156 if (name && name[0])157 m_thread_name.assign(name);158 else159 m_thread_name.clear();160 }161 162 llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>163 GetSiginfo(size_t max_size) const override;164 165protected:166 // Member variables.167 std::string m_thread_name;168 lldb::RegisterContextSP m_thread_reg_ctx_sp;169 170 lldb_private::DataExtractor m_gpregset_data;171 std::vector<lldb_private::CoreNote> m_notes;172 llvm::StringRef m_siginfo_bytes;173 // Only used if no siginfo note.174 int m_signo;175 176 bool CalculateStopInfo() override;177};178 179#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H180