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