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 code = 0; 132 int prstatus_sig = 0; 133 std::string name; 134 }; 135 136 class ThreadElfCore : public lldb_private::Thread { 137 public: 138 ThreadElfCore(lldb_private::Process &process, const ThreadData &td); 139 140 ~ThreadElfCore() override; 141 142 void RefreshStateAfterStop() override; 143 144 lldb::RegisterContextSP GetRegisterContext() override; 145 146 lldb::RegisterContextSP 147 CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; 148 ThreadIDIsValid(lldb::tid_t thread)149 static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; } 150 GetName()151 const char *GetName() override { 152 if (m_thread_name.empty()) 153 return nullptr; 154 return m_thread_name.c_str(); 155 } 156 SetName(const char * name)157 void SetName(const char *name) override { 158 if (name && name[0]) 159 m_thread_name.assign(name); 160 else 161 m_thread_name.clear(); 162 } 163 164 protected: 165 // Member variables. 166 std::string m_thread_name; 167 lldb::RegisterContextSP m_thread_reg_ctx_sp; 168 169 int m_signo; 170 int m_code; 171 172 lldb_private::DataExtractor m_gpregset_data; 173 std::vector<lldb_private::CoreNote> m_notes; 174 175 bool CalculateStopInfo() override; 176 }; 177 178 #endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H 179