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