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