LLDB mainline
ThreadElfCore.cpp
Go to the documentation of this file.
1//===-- ThreadElfCore.cpp -------------------------------------------------===//
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
11#include "lldb/Target/Target.h"
12#include "lldb/Target/Unwind.h"
15#include "lldb/Utility/Log.h"
16
31#include "ProcessElfCore.h"
40#include "ThreadElfCore.h"
41
42#include <memory>
43
44using namespace lldb;
45using namespace lldb_private;
46
47// Construct a Thread object with given data
49 : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
50 m_signo(td.signo), m_code(td.code), m_gpregset_data(td.gpregset),
51 m_notes(td.notes) {}
52
54
56 GetRegisterContext()->InvalidateIfNeeded(false);
57}
58
60 if (!m_reg_context_sp) {
62 }
63 return m_reg_context_sp;
64}
65
68 RegisterContextSP reg_ctx_sp;
69 uint32_t concrete_frame_idx = 0;
70 Log *log = GetLog(LLDBLog::Thread);
71
72 if (frame)
73 concrete_frame_idx = frame->GetConcreteFrameIndex();
74
75 bool is_linux = false;
76 if (concrete_frame_idx == 0) {
79
80 ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
81 ArchSpec arch = process->GetArchitecture();
82 RegisterInfoInterface *reg_interface = nullptr;
83
84 switch (arch.GetTriple().getOS()) {
85 case llvm::Triple::FreeBSD: {
86 switch (arch.GetMachine()) {
87 case llvm::Triple::aarch64:
88 case llvm::Triple::arm:
89 break;
90 case llvm::Triple::ppc:
91 reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
92 break;
93 case llvm::Triple::ppc64:
94 reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
95 break;
96 case llvm::Triple::mips64:
97 reg_interface = new RegisterContextFreeBSD_mips64(arch);
98 break;
99 case llvm::Triple::x86:
100 reg_interface = new RegisterContextFreeBSD_i386(arch);
101 break;
102 case llvm::Triple::x86_64:
103 reg_interface = new RegisterContextFreeBSD_x86_64(arch);
104 break;
105 default:
106 break;
107 }
108 break;
109 }
110
111 case llvm::Triple::NetBSD: {
112 switch (arch.GetMachine()) {
113 case llvm::Triple::aarch64:
114 break;
115 case llvm::Triple::x86:
116 reg_interface = new RegisterContextNetBSD_i386(arch);
117 break;
118 case llvm::Triple::x86_64:
119 reg_interface = new RegisterContextNetBSD_x86_64(arch);
120 break;
121 default:
122 break;
123 }
124 break;
125 }
126
127 case llvm::Triple::Linux: {
128 is_linux = true;
129 switch (arch.GetMachine()) {
130 case llvm::Triple::aarch64:
131 break;
132 case llvm::Triple::ppc64le:
133 reg_interface = new RegisterInfoPOSIX_ppc64le(arch);
134 break;
135 case llvm::Triple::systemz:
136 reg_interface = new RegisterContextLinux_s390x(arch);
137 break;
138 case llvm::Triple::x86:
139 reg_interface = new RegisterContextLinux_i386(arch);
140 break;
141 case llvm::Triple::x86_64:
142 reg_interface = new RegisterContextLinux_x86_64(arch);
143 break;
144 default:
145 break;
146 }
147 break;
148 }
149
150 case llvm::Triple::OpenBSD: {
151 switch (arch.GetMachine()) {
152 case llvm::Triple::aarch64:
153 break;
154 case llvm::Triple::x86:
155 reg_interface = new RegisterContextOpenBSD_i386(arch);
156 break;
157 case llvm::Triple::x86_64:
158 reg_interface = new RegisterContextOpenBSD_x86_64(arch);
159 break;
160 default:
161 break;
162 }
163 break;
164 }
165
166 default:
167 break;
168 }
169
170 if (!reg_interface && arch.GetMachine() != llvm::Triple::aarch64 &&
171 arch.GetMachine() != llvm::Triple::arm) {
172 LLDB_LOGF(log, "elf-core::%s:: Architecture(%d) or OS(%d) not supported",
173 __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
174 assert(false && "Architecture or OS not supported");
175 }
176
177 switch (arch.GetMachine()) {
178 case llvm::Triple::aarch64:
180 *this, arch, m_gpregset_data, m_notes);
181 break;
182 case llvm::Triple::arm:
183 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm>(
184 *this, std::make_unique<RegisterInfoPOSIX_arm>(arch), m_gpregset_data,
185 m_notes);
186 break;
187 case llvm::Triple::mipsel:
188 case llvm::Triple::mips:
189 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_mips64>(
190 *this, reg_interface, m_gpregset_data, m_notes);
191 break;
192 case llvm::Triple::mips64:
193 case llvm::Triple::mips64el:
194 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_mips64>(
195 *this, reg_interface, m_gpregset_data, m_notes);
196 break;
197 case llvm::Triple::ppc:
198 case llvm::Triple::ppc64:
199 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_powerpc>(
200 *this, reg_interface, m_gpregset_data, m_notes);
201 break;
202 case llvm::Triple::ppc64le:
203 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_ppc64le>(
204 *this, reg_interface, m_gpregset_data, m_notes);
205 break;
206 case llvm::Triple::systemz:
207 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_s390x>(
208 *this, reg_interface, m_gpregset_data, m_notes);
209 break;
210 case llvm::Triple::x86:
211 case llvm::Triple::x86_64:
212 if (is_linux) {
213 m_thread_reg_ctx_sp = std::make_shared<RegisterContextLinuxCore_x86_64>(
214 *this, reg_interface, m_gpregset_data, m_notes);
215 } else {
216 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>(
217 *this, reg_interface, m_gpregset_data, m_notes);
218 }
219 break;
220 default:
221 break;
222 }
223
224 reg_ctx_sp = m_thread_reg_ctx_sp;
225 } else {
226 reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
227 }
228 return reg_ctx_sp;
229}
230
232 ProcessSP process_sp(GetProcess());
233 if (!process_sp)
234 return false;
235
237 *this, m_signo, /*description=*/nullptr, m_code));
238 return true;
239}
240
241// Parse PRSTATUS from NOTE entry
243 memset(this, 0, sizeof(ELFLinuxPrStatus));
244}
245
247 constexpr size_t mips_linux_pr_status_size_o32 = 96;
248 constexpr size_t mips_linux_pr_status_size_n32 = 72;
249 constexpr size_t num_ptr_size_members = 10;
250 if (arch.IsMIPS()) {
251 std::string abi = arch.GetTargetABI();
252 assert(!abi.empty() && "ABI is not set");
253 if (!abi.compare("n64"))
254 return sizeof(ELFLinuxPrStatus);
255 else if (!abi.compare("o32"))
256 return mips_linux_pr_status_size_o32;
257 // N32 ABI
258 return mips_linux_pr_status_size_n32;
259 }
260 switch (arch.GetCore()) {
263 return 72;
264 default:
265 if (arch.GetAddressByteSize() == 8)
266 return sizeof(ELFLinuxPrStatus);
267 else
268 return sizeof(ELFLinuxPrStatus) - num_ptr_size_members * 4;
269 }
270}
271
273 const ArchSpec &arch) {
275 if (GetSize(arch) > data.GetByteSize()) {
276 error.SetErrorStringWithFormat(
277 "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64,
278 GetSize(arch), data.GetByteSize());
279 return error;
280 }
281
282 // Read field by field to correctly account for endianess of both the core
283 // dump and the platform running lldb.
284 offset_t offset = 0;
285 si_signo = data.GetU32(&offset);
286 si_code = data.GetU32(&offset);
287 si_errno = data.GetU32(&offset);
288
289 pr_cursig = data.GetU16(&offset);
290 offset += 2; // pad
291
292 pr_sigpend = data.GetAddress(&offset);
293 pr_sighold = data.GetAddress(&offset);
294
295 pr_pid = data.GetU32(&offset);
296 pr_ppid = data.GetU32(&offset);
297 pr_pgrp = data.GetU32(&offset);
298 pr_sid = data.GetU32(&offset);
299
300 pr_utime.tv_sec = data.GetAddress(&offset);
301 pr_utime.tv_usec = data.GetAddress(&offset);
302
303 pr_stime.tv_sec = data.GetAddress(&offset);
304 pr_stime.tv_usec = data.GetAddress(&offset);
305
306 pr_cutime.tv_sec = data.GetAddress(&offset);
307 pr_cutime.tv_usec = data.GetAddress(&offset);
308
309 pr_cstime.tv_sec = data.GetAddress(&offset);
310 pr_cstime.tv_usec = data.GetAddress(&offset);
311
312 return error;
313}
314
315// Parse PRPSINFO from NOTE entry
317 memset(this, 0, sizeof(ELFLinuxPrPsInfo));
318}
319
321 constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128;
322 if (arch.IsMIPS()) {
323 uint8_t address_byte_size = arch.GetAddressByteSize();
324 if (address_byte_size == 8)
325 return sizeof(ELFLinuxPrPsInfo);
326 return mips_linux_pr_psinfo_size_o32_n32;
327 }
328
329 switch (arch.GetCore()) {
332 return sizeof(ELFLinuxPrPsInfo);
335 return 124;
336 default:
337 return 0;
338 }
339}
340
342 const ArchSpec &arch) {
344 ByteOrder byteorder = data.GetByteOrder();
345 if (GetSize(arch) > data.GetByteSize()) {
346 error.SetErrorStringWithFormat(
347 "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64,
348 GetSize(arch), data.GetByteSize());
349 return error;
350 }
351 size_t size = 0;
352 offset_t offset = 0;
353
354 pr_state = data.GetU8(&offset);
355 pr_sname = data.GetU8(&offset);
356 pr_zomb = data.GetU8(&offset);
357 pr_nice = data.GetU8(&offset);
358 if (data.GetAddressByteSize() == 8) {
359 // Word align the next field on 64 bit.
360 offset += 4;
361 }
362
363 pr_flag = data.GetAddress(&offset);
364
365 if (arch.IsMIPS()) {
366 // The pr_uid and pr_gid is always 32 bit irrespective of platforms
367 pr_uid = data.GetU32(&offset);
368 pr_gid = data.GetU32(&offset);
369 } else {
370 // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms
371 pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
372 pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
373 }
374
375 pr_pid = data.GetU32(&offset);
376 pr_ppid = data.GetU32(&offset);
377 pr_pgrp = data.GetU32(&offset);
378 pr_sid = data.GetU32(&offset);
379
380 size = 16;
381 data.ExtractBytes(offset, size, byteorder, pr_fname);
382 offset += size;
383
384 size = 80;
385 data.ExtractBytes(offset, size, byteorder, pr_psargs);
386 offset += size;
387
388 return error;
389}
390
391// Parse SIGINFO from NOTE entry
393
395 if (arch.IsMIPS())
396 return sizeof(ELFLinuxSigInfo);
397 switch (arch.GetCore()) {
399 return sizeof(ELFLinuxSigInfo);
403 return 12;
404 default:
405 return 0;
406 }
407}
408
411 if (GetSize(arch) > data.GetByteSize()) {
412 error.SetErrorStringWithFormat(
413 "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64,
414 GetSize(arch), data.GetByteSize());
415 return error;
416 }
417
418 // Parsing from a 32 bit ELF core file, and populating/reusing the structure
419 // properly, because the struct is for the 64 bit version
420 offset_t offset = 0;
421 si_signo = data.GetU32(&offset);
422 si_errno = data.GetU32(&offset);
423 si_code = data.GetU32(&offset);
424
425 return error;
426}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
Definition: Log.h:349
lldb_private::ArchSpec GetArchitecture()
static std::unique_ptr< RegisterContextCorePOSIX_arm64 > Create(lldb_private::Thread &thread, const lldb_private::ArchSpec &arch, const lldb_private::DataExtractor &gpregset, llvm::ArrayRef< lldb_private::CoreNote > notes)
void RefreshStateAfterStop() override
lldb::RegisterContextSP GetRegisterContext() override
~ThreadElfCore() override
ThreadElfCore(lldb_private::Process &process, const ThreadData &td)
lldb::RegisterContextSP CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override
std::vector< lldb_private::CoreNote > m_notes
lldb::RegisterContextSP m_thread_reg_ctx_sp
lldb_private::DataExtractor m_gpregset_data
bool CalculateStopInfo() override
Ask the thread subclass to set its stop info.
An architecture specification class.
Definition: ArchSpec.h:31
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:691
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:450
bool IsMIPS() const
if MIPS architecture return true.
Definition: ArchSpec.cpp:559
std::string GetTargetABI() const
Return a string representing target application ABI.
Definition: ArchSpec.cpp:561
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:683
Core GetCore() const
Definition: ArchSpec.h:429
An data extractor class.
Definition: DataExtractor.h:48
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
uint64_t GetAddress(lldb::offset_t *offset_ptr) const
Extract an address from *offset_ptr.
uint16_t GetU16(lldb::offset_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
uint32_t GetAddressByteSize() const
Get the current address size.
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
uint8_t GetU8(lldb::offset_t *offset_ptr) const
Extract a uint8_t value from *offset_ptr.
size_t ExtractBytes(lldb::offset_t offset, lldb::offset_t length, lldb::ByteOrder dst_byte_order, void *dst) const
Extract an arbitrary number of bytes in the specified byte order.
A plug-in interface definition class for debugging a process.
Definition: Process.h:340
RegisterInfo interface to patch RegisterInfo structure for archs.
This base class provides an interface to stack frames.
Definition: StackFrame.h:42
uint32_t GetConcreteFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList, not counting inlined frame...
Definition: StackFrame.h:428
An error handling class.
Definition: Status.h:44
static lldb::StopInfoSP CreateStopReasonWithSignal(Thread &thread, int signo, const char *description=nullptr, std::optional< int > code=std::nullopt)
Definition: StopInfo.cpp:1386
void SetStopInfo(const lldb::StopInfoSP &stop_info_sp)
Definition: Thread.cpp:457
virtual void DestroyThread()
Definition: Thread.cpp:245
virtual Unwind & GetUnwinder()
Definition: Thread.cpp:1888
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
lldb::RegisterContextSP m_reg_context_sp
The register context for this thread's current register state.
Definition: Thread.h:1316
lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame)
Definition: Unwind.h:56
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:314
Definition: SBAddress.h:15
uint64_t offset_t
Definition: lldb-types.h:83
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:381
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
Definition: lldb-forward.h:386
lldb_private::Status Parse(const lldb_private::DataExtractor &data, const lldb_private::ArchSpec &arch)
static size_t GetSize(const lldb_private::ArchSpec &arch)
static size_t GetSize(const lldb_private::ArchSpec &arch)
uint64_t pr_sighold
Definition: ThreadElfCore.h:42
compat_timeval pr_cutime
Definition: ThreadElfCore.h:51
lldb_private::Status Parse(const lldb_private::DataExtractor &data, const lldb_private::ArchSpec &arch)
uint64_t pr_sigpend
Definition: ThreadElfCore.h:41
compat_timeval pr_stime
Definition: ThreadElfCore.h:50
compat_timeval pr_utime
Definition: ThreadElfCore.h:49
compat_timeval pr_cstime
Definition: ThreadElfCore.h:52
lldb_private::Status Parse(const lldb_private::DataExtractor &data, const lldb_private::ArchSpec &arch)
static size_t GetSize(const lldb_private::ArchSpec &arch)
uint64_t tv_sec
Definition: ThreadElfCore.h:19
uint64_t tv_usec
Definition: ThreadElfCore.h:20