brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · da0fb04 Raw
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