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