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