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
21struct compat_timeval {
22 alignas(8) uint64_t tv_sec;
23 alignas(8) uint64_t tv_usec;
24};
25
26namespace lldb_private {
27class 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
43struct 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
79static_assert(sizeof(ELFLinuxPrStatus) == 112,
80 "sizeof ELFLinuxPrStatus is not correct!");
81
82struct 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
96struct 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
131static_assert(sizeof(ELFLinuxPrPsInfo) == 136,
132 "sizeof ELFLinuxPrPsInfo is not correct!");
133
134class ThreadElfCore : public lldb_private::Thread {
135public:
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
147 static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
148
149 const char *GetName() override {
150 if (m_thread_name.empty())
151 return nullptr;
152 return m_thread_name.c_str();
153 }
154
155 void SetName(const char *name) override {
156 if (name && name[0])
157 m_thread_name.assign(s: 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
165protected:
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

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of lldb/source/Plugins/Process/elf-core/ThreadElfCore.h