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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H 10 #define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H 11 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 21 struct compat_timeval { 22 alignas(8) uint64_t tv_sec; 23 alignas(8) uint64_t tv_usec; 24 }; 25 26 namespace lldb_private { 27 class 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 again 33 // in the same structure 34 // The gp registers are also a part of this struct, but they are handled 35 // separately 36 37 #undef si_signo 38 #undef si_code 39 #undef si_errno 40 #undef si_addr 41 #undef si_addr_lsb 42 43 struct 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 structure 72 // 64 bit - just sizeof 73 // 32 bit - hardcoded because we are reusing the struct, but some of the 74 // members are smaller - 75 // so the layout is not the same 76 static size_t GetSize(const lldb_private::ArchSpec &arch); 77 }; 78 79 static_assert(sizeof(ELFLinuxPrStatus) == 112, 80 "sizeof ELFLinuxPrStatus is not correct!"); 81 82 struct 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 again 95 // in the same structure 96 struct 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 structure 124 // 64 bit - just sizeof 125 // 32 bit - hardcoded because we are reusing the struct, but some of the 126 // members are smaller - 127 // so the layout is not the same 128 static size_t GetSize(const lldb_private::ArchSpec &arch); 129 }; 130 131 static_assert(sizeof(ELFLinuxPrPsInfo) == 136, 132 "sizeof ELFLinuxPrPsInfo is not correct!"); 133 134 class ThreadElfCore : public lldb_private::Thread { 135 public: 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::RegisterContextSP 145 CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; 146 ThreadIDIsValid(lldb::tid_t thread)147 static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; } 148 GetName()149 const char *GetName() override { 150 if (m_thread_name.empty()) 151 return nullptr; 152 return m_thread_name.c_str(); 153 } 154 SetName(const char * name)155 void SetName(const char *name) override { 156 if (name && name[0]) 157 m_thread_name.assign(name); 158 else 159 m_thread_name.clear(); 160 } 161 162 llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> 163 GetSiginfo(size_t max_size) const override; 164 165 protected: 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_H 180