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/Thread.h" 14 #include "lldb/Utility/DataExtractor.h" 15 #include "llvm/ADT/DenseMap.h" 16 #include <optional> 17 #include <string> 18 19 struct compat_timeval { 20 alignas(8) uint64_t tv_sec; 21 alignas(8) uint64_t tv_usec; 22 }; 23 24 namespace lldb_private { 25 class ProcessInstanceInfo; 26 } 27 28 // PRSTATUS structure's size differs based on architecture. 29 // This is the layout in the x86-64 arch. 30 // In the i386 case we parse it manually and fill it again 31 // in the same structure 32 // The gp registers are also a part of this struct, but they are handled 33 // separately 34 35 #undef si_signo 36 #undef si_code 37 #undef si_errno 38 39 struct ELFLinuxPrStatus { 40 int32_t si_signo; 41 int32_t si_code; 42 int32_t si_errno; 43 44 int16_t pr_cursig; 45 46 alignas(8) uint64_t pr_sigpend; 47 alignas(8) uint64_t pr_sighold; 48 49 uint32_t pr_pid; 50 uint32_t pr_ppid; 51 uint32_t pr_pgrp; 52 uint32_t pr_sid; 53 54 compat_timeval pr_utime; 55 compat_timeval pr_stime; 56 compat_timeval pr_cutime; 57 compat_timeval pr_cstime; 58 59 ELFLinuxPrStatus(); 60 61 lldb_private::Status Parse(const lldb_private::DataExtractor &data, 62 const lldb_private::ArchSpec &arch); 63 64 static std::optional<ELFLinuxPrStatus> 65 Populate(const lldb::ThreadSP &thread_sp); 66 67 // Return the bytesize of the structure 68 // 64 bit - just sizeof 69 // 32 bit - hardcoded because we are reusing the struct, but some of the 70 // members are smaller - 71 // so the layout is not the same 72 static size_t GetSize(const lldb_private::ArchSpec &arch); 73 }; 74 75 static_assert(sizeof(ELFLinuxPrStatus) == 112, 76 "sizeof ELFLinuxPrStatus is not correct!"); 77 78 struct ELFLinuxSigInfo { 79 int32_t si_signo; 80 int32_t si_code; 81 int32_t si_errno; 82 83 ELFLinuxSigInfo(); 84 85 lldb_private::Status Parse(const lldb_private::DataExtractor &data, 86 const lldb_private::ArchSpec &arch); 87 88 // Return the bytesize of the structure 89 // 64 bit - just sizeof 90 // 32 bit - hardcoded because we are reusing the struct, but some of the 91 // members are smaller - 92 // so the layout is not the same 93 static size_t GetSize(const lldb_private::ArchSpec &arch); 94 }; 95 96 static_assert(sizeof(ELFLinuxSigInfo) == 12, 97 "sizeof ELFLinuxSigInfo is not correct!"); 98 99 // PRPSINFO structure's size differs based on architecture. 100 // This is the layout in the x86-64 arch case. 101 // In the i386 case we parse it manually and fill it again 102 // in the same structure 103 struct ELFLinuxPrPsInfo { 104 char pr_state; 105 char pr_sname; 106 char pr_zomb; 107 char pr_nice; 108 alignas(8) uint64_t pr_flag; 109 uint32_t pr_uid; 110 uint32_t pr_gid; 111 int32_t pr_pid; 112 int32_t pr_ppid; 113 int32_t pr_pgrp; 114 int32_t pr_sid; 115 char pr_fname[16]; 116 char pr_psargs[80]; 117 118 ELFLinuxPrPsInfo(); 119 120 lldb_private::Status Parse(const lldb_private::DataExtractor &data, 121 const lldb_private::ArchSpec &arch); 122 123 static std::optional<ELFLinuxPrPsInfo> 124 Populate(const lldb::ProcessSP &process_sp); 125 126 static std::optional<ELFLinuxPrPsInfo> 127 Populate(const lldb_private::ProcessInstanceInfo &info, 128 lldb::StateType state); 129 130 // Return the bytesize of the structure 131 // 64 bit - just sizeof 132 // 32 bit - hardcoded because we are reusing the struct, but some of the 133 // members are smaller - 134 // so the layout is not the same 135 static size_t GetSize(const lldb_private::ArchSpec &arch); 136 }; 137 138 static_assert(sizeof(ELFLinuxPrPsInfo) == 136, 139 "sizeof ELFLinuxPrPsInfo is not correct!"); 140 141 struct ThreadData { 142 lldb_private::DataExtractor gpregset; 143 std::vector<lldb_private::CoreNote> notes; 144 lldb::tid_t tid; 145 int signo = 0; 146 int code = 0; 147 int prstatus_sig = 0; 148 std::string name; 149 }; 150 151 class ThreadElfCore : public lldb_private::Thread { 152 public: 153 ThreadElfCore(lldb_private::Process &process, const ThreadData &td); 154 155 ~ThreadElfCore() override; 156 157 void RefreshStateAfterStop() override; 158 159 lldb::RegisterContextSP GetRegisterContext() override; 160 161 lldb::RegisterContextSP 162 CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; 163 164 static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; } 165 166 const char *GetName() override { 167 if (m_thread_name.empty()) 168 return nullptr; 169 return m_thread_name.c_str(); 170 } 171 172 void SetName(const char *name) override { 173 if (name && name[0]) 174 m_thread_name.assign(name); 175 else 176 m_thread_name.clear(); 177 } 178 179 protected: 180 // Member variables. 181 std::string m_thread_name; 182 lldb::RegisterContextSP m_thread_reg_ctx_sp; 183 184 int m_signo; 185 int m_code; 186 187 lldb_private::DataExtractor m_gpregset_data; 188 std::vector<lldb_private::CoreNote> m_notes; 189 190 bool CalculateStopInfo() override; 191 }; 192 193 #endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H 194