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