xref: /llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h (revision a434cac523da6db542350fd747967520aaae8fbb)
1 //===-- ThreadElfCore.h -----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H
10 #define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H
11 
12 #include "Plugins/Process/elf-core/RegisterUtilities.h"
13 #include "lldb/Target/Thread.h"
14 #include "lldb/Utility/DataExtractor.h"
15 #include "llvm/ADT/DenseMap.h"
16 #include <optional>
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 namespace lldb_private {
25 class ProcessInstanceInfo;
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(const lldb_private::DataExtractor &data,
62                              const lldb_private::ArchSpec &arch);
63 
64   static std::optional<ELFLinuxPrStatus>
65   Populate(const lldb::ThreadSP &thread_sp);
66 
67   // Return the bytesize of the structure
68   // 64 bit - just sizeof
69   // 32 bit - hardcoded because we are reusing the struct, but some of the
70   // members are smaller -
71   // so the layout is not the same
72   static size_t GetSize(const lldb_private::ArchSpec &arch);
73 };
74 
75 static_assert(sizeof(ELFLinuxPrStatus) == 112,
76               "sizeof ELFLinuxPrStatus is not correct!");
77 
78 struct ELFLinuxSigInfo {
79   int32_t si_signo;
80   int32_t si_code;
81   int32_t si_errno;
82 
83   ELFLinuxSigInfo();
84 
85   lldb_private::Status Parse(const lldb_private::DataExtractor &data,
86                              const lldb_private::ArchSpec &arch);
87 
88   // Return the bytesize of the structure
89   // 64 bit - just sizeof
90   // 32 bit - hardcoded because we are reusing the struct, but some of the
91   // members are smaller -
92   // so the layout is not the same
93   static size_t GetSize(const lldb_private::ArchSpec &arch);
94 };
95 
96 static_assert(sizeof(ELFLinuxSigInfo) == 12,
97               "sizeof ELFLinuxSigInfo is not correct!");
98 
99 // PRPSINFO structure's size differs based on architecture.
100 // This is the layout in the x86-64 arch case.
101 // In the i386 case we parse it manually and fill it again
102 // in the same structure
103 struct ELFLinuxPrPsInfo {
104   char pr_state;
105   char pr_sname;
106   char pr_zomb;
107   char pr_nice;
108   alignas(8) uint64_t pr_flag;
109   uint32_t pr_uid;
110   uint32_t pr_gid;
111   int32_t pr_pid;
112   int32_t pr_ppid;
113   int32_t pr_pgrp;
114   int32_t pr_sid;
115   char pr_fname[16];
116   char pr_psargs[80];
117 
118   ELFLinuxPrPsInfo();
119 
120   lldb_private::Status Parse(const lldb_private::DataExtractor &data,
121                              const lldb_private::ArchSpec &arch);
122 
123   static std::optional<ELFLinuxPrPsInfo>
124   Populate(const lldb::ProcessSP &process_sp);
125 
126   static std::optional<ELFLinuxPrPsInfo>
127   Populate(const lldb_private::ProcessInstanceInfo &info,
128            lldb::StateType state);
129 
130   // Return the bytesize of the structure
131   // 64 bit - just sizeof
132   // 32 bit - hardcoded because we are reusing the struct, but some of the
133   // members are smaller -
134   // so the layout is not the same
135   static size_t GetSize(const lldb_private::ArchSpec &arch);
136 };
137 
138 static_assert(sizeof(ELFLinuxPrPsInfo) == 136,
139               "sizeof ELFLinuxPrPsInfo is not correct!");
140 
141 struct ThreadData {
142   lldb_private::DataExtractor gpregset;
143   std::vector<lldb_private::CoreNote> notes;
144   lldb::tid_t tid;
145   int signo = 0;
146   int code = 0;
147   int prstatus_sig = 0;
148   std::string name;
149 };
150 
151 class ThreadElfCore : public lldb_private::Thread {
152 public:
153   ThreadElfCore(lldb_private::Process &process, const ThreadData &td);
154 
155   ~ThreadElfCore() override;
156 
157   void RefreshStateAfterStop() override;
158 
159   lldb::RegisterContextSP GetRegisterContext() override;
160 
161   lldb::RegisterContextSP
162   CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
163 
164   static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
165 
166   const char *GetName() override {
167     if (m_thread_name.empty())
168       return nullptr;
169     return m_thread_name.c_str();
170   }
171 
172   void SetName(const char *name) override {
173     if (name && name[0])
174       m_thread_name.assign(name);
175     else
176       m_thread_name.clear();
177   }
178 
179 protected:
180   // Member variables.
181   std::string m_thread_name;
182   lldb::RegisterContextSP m_thread_reg_ctx_sp;
183 
184   int m_signo;
185   int m_code;
186 
187   lldb_private::DataExtractor m_gpregset_data;
188   std::vector<lldb_private::CoreNote> m_notes;
189 
190   bool CalculateStopInfo() override;
191 };
192 
193 #endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H
194