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 #include "Plugins/Process/elf-core/RegisterUtilities.h"
14 #include "lldb/Target/Thread.h"
15 #include "lldb/Utility/DataExtractor.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include <string>
18 
19 struct compat_timeval {
20   alignas(8) uint64_t tv_sec;
21   alignas(8) uint64_t tv_usec;
22 };
23 
24 // PRSTATUS structure's size differs based on architecture.
25 // This is the layout in the x86-64 arch.
26 // In the i386 case we parse it manually and fill it again
27 // in the same structure
28 // The gp registers are also a part of this struct, but they are handled
29 // separately
30 
31 #undef si_signo
32 #undef si_code
33 #undef si_errno
34 
35 struct ELFLinuxPrStatus {
36   int32_t si_signo;
37   int32_t si_code;
38   int32_t si_errno;
39 
40   int16_t pr_cursig;
41 
42   alignas(8) uint64_t pr_sigpend;
43   alignas(8) uint64_t pr_sighold;
44 
45   uint32_t pr_pid;
46   uint32_t pr_ppid;
47   uint32_t pr_pgrp;
48   uint32_t pr_sid;
49 
50   compat_timeval pr_utime;
51   compat_timeval pr_stime;
52   compat_timeval pr_cutime;
53   compat_timeval pr_cstime;
54 
55   ELFLinuxPrStatus();
56 
57   lldb_private::Status Parse(const lldb_private::DataExtractor &data,
58                              const lldb_private::ArchSpec &arch);
59 
60   // Return the bytesize of the structure
61   // 64 bit - just sizeof
62   // 32 bit - hardcoded because we are reusing the struct, but some of the
63   // members are smaller -
64   // so the layout is not the same
65   static size_t GetSize(const lldb_private::ArchSpec &arch);
66 };
67 
68 static_assert(sizeof(ELFLinuxPrStatus) == 112,
69               "sizeof ELFLinuxPrStatus is not correct!");
70 
71 struct ELFLinuxSigInfo {
72   int32_t si_signo;
73   int32_t si_code;
74   int32_t si_errno;
75 
76   ELFLinuxSigInfo();
77 
78   lldb_private::Status Parse(const lldb_private::DataExtractor &data,
79                              const lldb_private::ArchSpec &arch);
80 
81   // Return the bytesize of the structure
82   // 64 bit - just sizeof
83   // 32 bit - hardcoded because we are reusing the struct, but some of the
84   // members are smaller -
85   // so the layout is not the same
86   static size_t GetSize(const lldb_private::ArchSpec &arch);
87 };
88 
89 static_assert(sizeof(ELFLinuxSigInfo) == 12,
90               "sizeof ELFLinuxSigInfo is not correct!");
91 
92 // PRPSINFO structure's size differs based on architecture.
93 // This is the layout in the x86-64 arch case.
94 // In the i386 case we parse it manually and fill it again
95 // in the same structure
96 struct ELFLinuxPrPsInfo {
97   char pr_state;
98   char pr_sname;
99   char pr_zomb;
100   char pr_nice;
101   alignas(8) uint64_t pr_flag;
102   uint32_t pr_uid;
103   uint32_t pr_gid;
104   int32_t pr_pid;
105   int32_t pr_ppid;
106   int32_t pr_pgrp;
107   int32_t pr_sid;
108   char pr_fname[16];
109   char pr_psargs[80];
110 
111   ELFLinuxPrPsInfo();
112 
113   lldb_private::Status Parse(const lldb_private::DataExtractor &data,
114                              const lldb_private::ArchSpec &arch);
115 
116   // Return the bytesize of the structure
117   // 64 bit - just sizeof
118   // 32 bit - hardcoded because we are reusing the struct, but some of the
119   // members are smaller -
120   // so the layout is not the same
121   static size_t GetSize(const lldb_private::ArchSpec &arch);
122 };
123 
124 static_assert(sizeof(ELFLinuxPrPsInfo) == 136,
125               "sizeof ELFLinuxPrPsInfo is not correct!");
126 
127 struct ThreadData {
128   lldb_private::DataExtractor gpregset;
129   std::vector<lldb_private::CoreNote> notes;
130   lldb::tid_t tid;
131   int signo = 0;
132   int prstatus_sig = 0;
133   std::string name;
134 };
135 
136 class ThreadElfCore : public lldb_private::Thread {
137 public:
138   ThreadElfCore(lldb_private::Process &process, const ThreadData &td);
139 
140   ~ThreadElfCore() override;
141 
142   void RefreshStateAfterStop() override;
143 
144   lldb::RegisterContextSP GetRegisterContext() override;
145 
146   lldb::RegisterContextSP
147   CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
148 
149   static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
150 
151   const char *GetName() override {
152     if (m_thread_name.empty())
153       return NULL;
154     return m_thread_name.c_str();
155   }
156 
157   void SetName(const char *name) override {
158     if (name && name[0])
159       m_thread_name.assign(name);
160     else
161       m_thread_name.clear();
162   }
163 
164 protected:
165   //------------------------------------------------------------------
166   // Member variables.
167   //------------------------------------------------------------------
168   std::string m_thread_name;
169   lldb::RegisterContextSP m_thread_reg_ctx_sp;
170 
171   int m_signo;
172 
173   lldb_private::DataExtractor m_gpregset_data;
174   std::vector<lldb_private::CoreNote> m_notes;
175 
176   bool CalculateStopInfo() override;
177 };
178 
179 #endif // liblldb_ThreadElfCore_h_
180