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/Target/Thread.h" 20 #include "lldb/Core/DataExtractor.h" 21 22 struct compat_timeval 23 { 24 alignas(8) uint64_t tv_sec; 25 alignas(8) uint64_t tv_usec; 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 separately 33 34 #undef si_signo 35 #undef si_code 36 #undef si_errno 37 38 struct ELFLinuxPrStatus 39 { 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::Error 62 Parse(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch); 63 64 // Return the bytesize of the structure 65 // 64 bit - just sizeof 66 // 32 bit - hardcoded because we are reusing the struct, but some of the members are smaller - 67 // so the layout is not the same 68 static size_t 69 GetSize(lldb_private::ArchSpec &arch) 70 { 71 switch(arch.GetCore()) 72 { 73 case lldb_private::ArchSpec::eCore_s390x_generic: 74 case lldb_private::ArchSpec::eCore_x86_64_x86_64: 75 return sizeof(ELFLinuxPrStatus); 76 case lldb_private::ArchSpec::eCore_x86_32_i386: 77 case lldb_private::ArchSpec::eCore_x86_32_i486: 78 return 72; 79 default: 80 return 0; 81 } 82 } 83 }; 84 85 static_assert(sizeof(ELFLinuxPrStatus) == 112, "sizeof ELFLinuxPrStatus is not correct!"); 86 87 // PRPSINFO structure's size differs based on architecture. 88 // This is the layout in the x86-64 arch case. 89 // In the i386 case we parse it manually and fill it again 90 // in the same structure 91 struct ELFLinuxPrPsInfo 92 { 93 char pr_state; 94 char pr_sname; 95 char pr_zomb; 96 char pr_nice; 97 alignas(8) uint64_t pr_flag; 98 uint32_t pr_uid; 99 uint32_t pr_gid; 100 int32_t pr_pid; 101 int32_t pr_ppid; 102 int32_t pr_pgrp; 103 int32_t pr_sid; 104 char pr_fname[16]; 105 char pr_psargs[80]; 106 107 ELFLinuxPrPsInfo(); 108 109 lldb_private::Error 110 Parse(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch); 111 112 // Return the bytesize of the structure 113 // 64 bit - just sizeof 114 // 32 bit - hardcoded because we are reusing the struct, but some of the members are smaller - 115 // so the layout is not the same 116 static size_t 117 GetSize(lldb_private::ArchSpec &arch) 118 { 119 switch(arch.GetCore()) 120 { 121 case lldb_private::ArchSpec::eCore_s390x_generic: 122 case lldb_private::ArchSpec::eCore_x86_64_x86_64: 123 return sizeof(ELFLinuxPrPsInfo); 124 case lldb_private::ArchSpec::eCore_x86_32_i386: 125 case lldb_private::ArchSpec::eCore_x86_32_i486: 126 return 124; 127 default: 128 return 0; 129 } 130 } 131 }; 132 133 static_assert(sizeof(ELFLinuxPrPsInfo) == 136, "sizeof ELFLinuxPrPsInfo is not correct!"); 134 135 struct ThreadData 136 { 137 lldb_private::DataExtractor gpregset; 138 lldb_private::DataExtractor fpregset; 139 lldb_private::DataExtractor vregset; 140 lldb::tid_t tid; 141 int signo; 142 std::string name; 143 }; 144 145 class ThreadElfCore : public lldb_private::Thread 146 { 147 public: 148 ThreadElfCore (lldb_private::Process &process, const ThreadData &td); 149 150 ~ThreadElfCore() override; 151 152 void 153 RefreshStateAfterStop() override; 154 155 lldb::RegisterContextSP 156 GetRegisterContext() override; 157 158 lldb::RegisterContextSP 159 CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; 160 161 void 162 ClearStackFrames() override; 163 164 static bool 165 ThreadIDIsValid (lldb::tid_t thread) 166 { 167 return thread != 0; 168 } 169 170 const char * 171 GetName() override 172 { 173 if (m_thread_name.empty()) 174 return NULL; 175 return m_thread_name.c_str(); 176 } 177 178 void 179 SetName(const char *name) override 180 { 181 if (name && name[0]) 182 m_thread_name.assign (name); 183 else 184 m_thread_name.clear(); 185 } 186 187 protected: 188 //------------------------------------------------------------------ 189 // Member variables. 190 //------------------------------------------------------------------ 191 std::string m_thread_name; 192 lldb::RegisterContextSP m_thread_reg_ctx_sp; 193 194 int m_signo; 195 196 lldb_private::DataExtractor m_gpregset_data; 197 lldb_private::DataExtractor m_fpregset_data; 198 lldb_private::DataExtractor m_vregset_data; 199 200 bool CalculateStopInfo() override; 201 }; 202 203 #endif // liblldb_ThreadElfCore_h_ 204