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 
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::Status 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 };
70 
71 static_assert(sizeof(ELFLinuxPrStatus) == 112,
72               "sizeof ELFLinuxPrStatus is not correct!");
73 
74 struct ELFLinuxSigInfo {
75   int32_t si_signo;
76   int32_t si_code;
77   int32_t si_errno;
78 
79   ELFLinuxSigInfo();
80 
81   lldb_private::Status Parse(lldb_private::DataExtractor &data,
82                              const lldb_private::ArchSpec &arch);
83 
84   // Return the bytesize of the structure
85   // 64 bit - just sizeof
86   // 32 bit - hardcoded because we are reusing the struct, but some of the
87   // members are smaller -
88   // so the layout is not the same
89   static size_t GetSize(const lldb_private::ArchSpec &arch);
90 };
91 
92 static_assert(sizeof(ELFLinuxSigInfo) == 12,
93               "sizeof ELFLinuxSigInfo is not correct!");
94 
95 // PRPSINFO structure's size differs based on architecture.
96 // This is the layout in the x86-64 arch case.
97 // In the i386 case we parse it manually and fill it again
98 // in the same structure
99 struct ELFLinuxPrPsInfo {
100   char pr_state;
101   char pr_sname;
102   char pr_zomb;
103   char pr_nice;
104   alignas(8) uint64_t pr_flag;
105   uint32_t pr_uid;
106   uint32_t pr_gid;
107   int32_t pr_pid;
108   int32_t pr_ppid;
109   int32_t pr_pgrp;
110   int32_t pr_sid;
111   char pr_fname[16];
112   char pr_psargs[80];
113 
114   ELFLinuxPrPsInfo();
115 
116   lldb_private::Status Parse(lldb_private::DataExtractor &data,
117                              lldb_private::ArchSpec &arch);
118 
119   // Return the bytesize of the structure
120   // 64 bit - just sizeof
121   // 32 bit - hardcoded because we are reusing the struct, but some of the
122   // members are smaller -
123   // so the layout is not the same
124   static size_t GetSize(lldb_private::ArchSpec &arch);
125 };
126 
127 static_assert(sizeof(ELFLinuxPrPsInfo) == 136,
128               "sizeof ELFLinuxPrPsInfo is not correct!");
129 
130 struct ThreadData {
131   lldb_private::DataExtractor gpregset;
132   lldb_private::DataExtractor fpregset;
133   lldb_private::DataExtractor vregset;
134   lldb::tid_t tid;
135   int signo = 0;
136   int prstatus_sig = 0;
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