1 //===-- ThreadElfCore.h -----------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_ThreadElfCore_h_ 11 #define liblldb_ThreadElfCore_h_ 12 13 // C Includes 14 // C++ Includes 15 #include <string> 16 17 // Other libraries and framework includes 18 // Project includes 19 #include "lldb/Core/DataExtractor.h" 20 #include "lldb/Target/Thread.h" 21 22 struct compat_timeval { 23 alignas(8) uint64_t tv_sec; 24 alignas(8) uint64_t tv_usec; 25 }; 26 27 // PRSTATUS structure's size differs based on architecture. 28 // This is the layout in the x86-64 arch. 29 // In the i386 case we parse it manually and fill it again 30 // in the same structure 31 // The gp registers are also a part of this struct, but they are handled 32 // separately 33 34 #undef si_signo 35 #undef si_code 36 #undef si_errno 37 38 struct ELFLinuxPrStatus { 39 int32_t si_signo; 40 int32_t si_code; 41 int32_t si_errno; 42 43 int16_t pr_cursig; 44 45 alignas(8) uint64_t pr_sigpend; 46 alignas(8) uint64_t pr_sighold; 47 48 uint32_t pr_pid; 49 uint32_t pr_ppid; 50 uint32_t pr_pgrp; 51 uint32_t pr_sid; 52 53 compat_timeval pr_utime; 54 compat_timeval pr_stime; 55 compat_timeval pr_cutime; 56 compat_timeval pr_cstime; 57 58 ELFLinuxPrStatus(); 59 60 lldb_private::Error Parse(lldb_private::DataExtractor &data, 61 lldb_private::ArchSpec &arch); 62 63 // Return the bytesize of the structure 64 // 64 bit - just sizeof 65 // 32 bit - hardcoded because we are reusing the struct, but some of the 66 // members are smaller - 67 // so the layout is not the same 68 static size_t GetSize(lldb_private::ArchSpec &arch) { 69 switch (arch.GetCore()) { 70 case lldb_private::ArchSpec::eCore_s390x_generic: 71 case lldb_private::ArchSpec::eCore_x86_64_x86_64: 72 return sizeof(ELFLinuxPrStatus); 73 case lldb_private::ArchSpec::eCore_x86_32_i386: 74 case lldb_private::ArchSpec::eCore_x86_32_i486: 75 return 72; 76 default: 77 return 0; 78 } 79 } 80 }; 81 82 static_assert(sizeof(ELFLinuxPrStatus) == 112, 83 "sizeof ELFLinuxPrStatus is not correct!"); 84 85 struct ELFLinuxSigInfo { 86 int32_t si_signo; 87 int32_t si_code; 88 int32_t si_errno; 89 90 ELFLinuxSigInfo(); 91 92 lldb_private::Error Parse(lldb_private::DataExtractor &data, 93 const lldb_private::ArchSpec &arch); 94 95 // Return the bytesize of the structure 96 // 64 bit - just sizeof 97 // 32 bit - hardcoded because we are reusing the struct, but some of the 98 // members are smaller - 99 // so the layout is not the same 100 static size_t GetSize(const lldb_private::ArchSpec &arch) { 101 switch (arch.GetCore()) { 102 case lldb_private::ArchSpec::eCore_x86_64_x86_64: 103 return sizeof(ELFLinuxSigInfo); 104 case lldb_private::ArchSpec::eCore_s390x_generic: 105 case lldb_private::ArchSpec::eCore_x86_32_i386: 106 case lldb_private::ArchSpec::eCore_x86_32_i486: 107 return 12; 108 default: 109 return 0; 110 } 111 } 112 }; 113 114 static_assert(sizeof(ELFLinuxSigInfo) == 12, 115 "sizeof ELFLinuxSigInfo is not correct!"); 116 117 // PRPSINFO structure's size differs based on architecture. 118 // This is the layout in the x86-64 arch case. 119 // In the i386 case we parse it manually and fill it again 120 // in the same structure 121 struct ELFLinuxPrPsInfo { 122 char pr_state; 123 char pr_sname; 124 char pr_zomb; 125 char pr_nice; 126 alignas(8) uint64_t pr_flag; 127 uint32_t pr_uid; 128 uint32_t pr_gid; 129 int32_t pr_pid; 130 int32_t pr_ppid; 131 int32_t pr_pgrp; 132 int32_t pr_sid; 133 char pr_fname[16]; 134 char pr_psargs[80]; 135 136 ELFLinuxPrPsInfo(); 137 138 lldb_private::Error Parse(lldb_private::DataExtractor &data, 139 lldb_private::ArchSpec &arch); 140 141 // Return the bytesize of the structure 142 // 64 bit - just sizeof 143 // 32 bit - hardcoded because we are reusing the struct, but some of the 144 // members are smaller - 145 // so the layout is not the same 146 static size_t GetSize(lldb_private::ArchSpec &arch) { 147 switch (arch.GetCore()) { 148 case lldb_private::ArchSpec::eCore_s390x_generic: 149 case lldb_private::ArchSpec::eCore_x86_64_x86_64: 150 return sizeof(ELFLinuxPrPsInfo); 151 case lldb_private::ArchSpec::eCore_x86_32_i386: 152 case lldb_private::ArchSpec::eCore_x86_32_i486: 153 return 124; 154 default: 155 return 0; 156 } 157 } 158 }; 159 160 static_assert(sizeof(ELFLinuxPrPsInfo) == 136, 161 "sizeof ELFLinuxPrPsInfo is not correct!"); 162 163 struct ThreadData { 164 lldb_private::DataExtractor gpregset; 165 lldb_private::DataExtractor fpregset; 166 lldb_private::DataExtractor vregset; 167 lldb::tid_t tid; 168 int signo = 0; 169 int prstatus_sig = 0; 170 std::string name; 171 }; 172 173 class ThreadElfCore : public lldb_private::Thread { 174 public: 175 ThreadElfCore(lldb_private::Process &process, const ThreadData &td); 176 177 ~ThreadElfCore() override; 178 179 void RefreshStateAfterStop() override; 180 181 lldb::RegisterContextSP GetRegisterContext() override; 182 183 lldb::RegisterContextSP 184 CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; 185 186 void ClearStackFrames() override; 187 188 static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; } 189 190 const char *GetName() override { 191 if (m_thread_name.empty()) 192 return NULL; 193 return m_thread_name.c_str(); 194 } 195 196 void SetName(const char *name) override { 197 if (name && name[0]) 198 m_thread_name.assign(name); 199 else 200 m_thread_name.clear(); 201 } 202 203 protected: 204 //------------------------------------------------------------------ 205 // Member variables. 206 //------------------------------------------------------------------ 207 std::string m_thread_name; 208 lldb::RegisterContextSP m_thread_reg_ctx_sp; 209 210 int m_signo; 211 212 lldb_private::DataExtractor m_gpregset_data; 213 lldb_private::DataExtractor m_fpregset_data; 214 lldb_private::DataExtractor m_vregset_data; 215 216 bool CalculateStopInfo() override; 217 }; 218 219 #endif // liblldb_ThreadElfCore_h_ 220