ThreadElfCore.cpp revision 353358
1254721Semaste//===-- ThreadElfCore.cpp --------------------------------------*- C++ -*-===//
2254721Semaste//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6254721Semaste//
7254721Semaste//===----------------------------------------------------------------------===//
8254721Semaste
9254721Semaste#include "lldb/Target/RegisterContext.h"
10254721Semaste#include "lldb/Target/StopInfo.h"
11254721Semaste#include "lldb/Target/Target.h"
12254721Semaste#include "lldb/Target/Unwind.h"
13321369Sdim#include "lldb/Utility/DataExtractor.h"
14321369Sdim#include "lldb/Utility/Log.h"
15254721Semaste
16280031Sdim#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
17280031Sdim#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
18280031Sdim#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
19280031Sdim#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
20327952Sdim#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
21327952Sdim#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
22321369Sdim#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
23327952Sdim#ifdef LLDB_ENABLE_ALL
24327952Sdim#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
25327952Sdim#endif // LLDB_ENABLE_ALL
26314564Sdim#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
27321369Sdim#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h"
28321369Sdim#include "Plugins/Process/Utility/RegisterContextOpenBSD_i386.h"
29321369Sdim#include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h"
30321369Sdim#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
31314564Sdim#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
32327952Sdim#include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h"
33314564Sdim#include "ProcessElfCore.h"
34288943Sdim#include "RegisterContextPOSIXCore_arm.h"
35288943Sdim#include "RegisterContextPOSIXCore_arm64.h"
36258054Semaste#include "RegisterContextPOSIXCore_mips64.h"
37280031Sdim#include "RegisterContextPOSIXCore_powerpc.h"
38327952Sdim#include "RegisterContextPOSIXCore_ppc64le.h"
39327952Sdim#ifdef LLDB_ENABLE_ALL
40327952Sdim#include "RegisterContextPOSIXCore_s390x.h"
41327952Sdim#endif // LLDB_ENABLE_ALL
42258054Semaste#include "RegisterContextPOSIXCore_x86_64.h"
43314564Sdim#include "ThreadElfCore.h"
44254721Semaste
45353358Sdim#include <memory>
46353358Sdim
47254721Semasteusing namespace lldb;
48254721Semasteusing namespace lldb_private;
49254721Semaste
50254721Semaste// Construct a Thread object with given data
51314564SdimThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td)
52314564Sdim    : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
53327952Sdim      m_signo(td.signo), m_gpregset_data(td.gpregset), m_notes(td.notes) {}
54254721Semaste
55314564SdimThreadElfCore::~ThreadElfCore() { DestroyThread(); }
56254721Semaste
57314564Sdimvoid ThreadElfCore::RefreshStateAfterStop() {
58314564Sdim  GetRegisterContext()->InvalidateIfNeeded(false);
59254721Semaste}
60254721Semaste
61314564SdimRegisterContextSP ThreadElfCore::GetRegisterContext() {
62341825Sdim  if (!m_reg_context_sp) {
63341825Sdim    m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
64314564Sdim  }
65314564Sdim  return m_reg_context_sp;
66254721Semaste}
67254721Semaste
68254721SemasteRegisterContextSP
69314564SdimThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
70314564Sdim  RegisterContextSP reg_ctx_sp;
71314564Sdim  uint32_t concrete_frame_idx = 0;
72314564Sdim  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
73254721Semaste
74314564Sdim  if (frame)
75314564Sdim    concrete_frame_idx = frame->GetConcreteFrameIndex();
76254721Semaste
77314564Sdim  if (concrete_frame_idx == 0) {
78314564Sdim    if (m_thread_reg_ctx_sp)
79314564Sdim      return m_thread_reg_ctx_sp;
80254721Semaste
81314564Sdim    ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
82314564Sdim    ArchSpec arch = process->GetArchitecture();
83341825Sdim    RegisterInfoInterface *reg_interface = nullptr;
84262528Semaste
85314564Sdim    switch (arch.GetTriple().getOS()) {
86314564Sdim    case llvm::Triple::FreeBSD: {
87314564Sdim      switch (arch.GetMachine()) {
88314564Sdim      case llvm::Triple::aarch64:
89314564Sdim        reg_interface = new RegisterInfoPOSIX_arm64(arch);
90314564Sdim        break;
91314564Sdim      case llvm::Triple::arm:
92321369Sdim        reg_interface = new RegisterInfoPOSIX_arm(arch);
93314564Sdim        break;
94314564Sdim      case llvm::Triple::ppc:
95314564Sdim        reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
96314564Sdim        break;
97314564Sdim      case llvm::Triple::ppc64:
98314564Sdim        reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
99314564Sdim        break;
100314564Sdim      case llvm::Triple::mips64:
101314564Sdim        reg_interface = new RegisterContextFreeBSD_mips64(arch);
102314564Sdim        break;
103314564Sdim      case llvm::Triple::x86:
104314564Sdim        reg_interface = new RegisterContextFreeBSD_i386(arch);
105314564Sdim        break;
106314564Sdim      case llvm::Triple::x86_64:
107314564Sdim        reg_interface = new RegisterContextFreeBSD_x86_64(arch);
108314564Sdim        break;
109314564Sdim      default:
110314564Sdim        break;
111314564Sdim      }
112314564Sdim      break;
113314564Sdim    }
114276479Sdim
115321369Sdim    case llvm::Triple::NetBSD: {
116321369Sdim      switch (arch.GetMachine()) {
117353358Sdim      case llvm::Triple::aarch64:
118353358Sdim        reg_interface = new RegisterInfoPOSIX_arm64(arch);
119353358Sdim        break;
120321369Sdim      case llvm::Triple::x86_64:
121321369Sdim        reg_interface = new RegisterContextNetBSD_x86_64(arch);
122321369Sdim        break;
123321369Sdim      default:
124321369Sdim        break;
125321369Sdim      }
126321369Sdim      break;
127321369Sdim    }
128321369Sdim
129314564Sdim    case llvm::Triple::Linux: {
130314564Sdim      switch (arch.GetMachine()) {
131314564Sdim      case llvm::Triple::arm:
132321369Sdim        reg_interface = new RegisterInfoPOSIX_arm(arch);
133314564Sdim        break;
134314564Sdim      case llvm::Triple::aarch64:
135314564Sdim        reg_interface = new RegisterInfoPOSIX_arm64(arch);
136314564Sdim        break;
137321369Sdim      case llvm::Triple::mipsel:
138321369Sdim      case llvm::Triple::mips:
139321369Sdim        reg_interface = new RegisterContextLinux_mips(arch);
140321369Sdim        break;
141321369Sdim      case llvm::Triple::mips64el:
142321369Sdim      case llvm::Triple::mips64:
143321369Sdim        reg_interface = new RegisterContextLinux_mips64(arch);
144321369Sdim        break;
145327952Sdim      case llvm::Triple::ppc64le:
146327952Sdim        reg_interface = new RegisterInfoPOSIX_ppc64le(arch);
147327952Sdim        break;
148327952Sdim#ifdef LLDB_ENABLE_ALL
149327952Sdim      case llvm::Triple::systemz:
150327952Sdim        reg_interface = new RegisterContextLinux_s390x(arch);
151327952Sdim        break;
152327952Sdim#endif // LLDB_ENABLE_ALL
153314564Sdim      case llvm::Triple::x86:
154314564Sdim        reg_interface = new RegisterContextLinux_i386(arch);
155314564Sdim        break;
156314564Sdim      case llvm::Triple::x86_64:
157314564Sdim        reg_interface = new RegisterContextLinux_x86_64(arch);
158314564Sdim        break;
159314564Sdim      default:
160314564Sdim        break;
161314564Sdim      }
162314564Sdim      break;
163314564Sdim    }
164262528Semaste
165321369Sdim    case llvm::Triple::OpenBSD: {
166321369Sdim      switch (arch.GetMachine()) {
167321369Sdim      case llvm::Triple::aarch64:
168321369Sdim        reg_interface = new RegisterInfoPOSIX_arm64(arch);
169321369Sdim        break;
170321369Sdim      case llvm::Triple::arm:
171321369Sdim        reg_interface = new RegisterInfoPOSIX_arm(arch);
172321369Sdim        break;
173321369Sdim      case llvm::Triple::x86:
174321369Sdim        reg_interface = new RegisterContextOpenBSD_i386(arch);
175321369Sdim        break;
176321369Sdim      case llvm::Triple::x86_64:
177321369Sdim        reg_interface = new RegisterContextOpenBSD_x86_64(arch);
178321369Sdim        break;
179321369Sdim      default:
180321369Sdim        break;
181321369Sdim      }
182321369Sdim      break;
183321369Sdim    }
184321369Sdim
185314564Sdim    default:
186314564Sdim      break;
187314564Sdim    }
188262528Semaste
189314564Sdim    if (!reg_interface) {
190314564Sdim      if (log)
191314564Sdim        log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
192314564Sdim                    __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
193314564Sdim      assert(false && "Architecture or OS not supported");
194314564Sdim    }
195262528Semaste
196314564Sdim    switch (arch.GetMachine()) {
197314564Sdim    case llvm::Triple::aarch64:
198353358Sdim      m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm64>(
199353358Sdim          *this, reg_interface, m_gpregset_data, m_notes);
200314564Sdim      break;
201314564Sdim    case llvm::Triple::arm:
202353358Sdim      m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm>(
203353358Sdim          *this, reg_interface, m_gpregset_data, m_notes);
204314564Sdim      break;
205321369Sdim    case llvm::Triple::mipsel:
206321369Sdim    case llvm::Triple::mips:
207353358Sdim      m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_mips64>(
208353358Sdim          *this, reg_interface, m_gpregset_data, m_notes);
209321369Sdim      break;
210314564Sdim    case llvm::Triple::mips64:
211321369Sdim    case llvm::Triple::mips64el:
212353358Sdim      m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_mips64>(
213353358Sdim          *this, reg_interface, m_gpregset_data, m_notes);
214314564Sdim      break;
215314564Sdim    case llvm::Triple::ppc:
216314564Sdim    case llvm::Triple::ppc64:
217353358Sdim      m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_powerpc>(
218353358Sdim          *this, reg_interface, m_gpregset_data, m_notes);
219314564Sdim      break;
220327952Sdim    case llvm::Triple::ppc64le:
221353358Sdim      m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_ppc64le>(
222353358Sdim          *this, reg_interface, m_gpregset_data, m_notes);
223327952Sdim      break;
224327952Sdim#ifdef LLDB_ENABLE_ALL
225327952Sdim    case llvm::Triple::systemz:
226353358Sdim      m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_s390x>(
227353358Sdim          *this, reg_interface, m_gpregset_data, m_notes);
228327952Sdim      break;
229327952Sdim#endif // LLDB_ENABLE_ALL
230314564Sdim    case llvm::Triple::x86:
231314564Sdim    case llvm::Triple::x86_64:
232353358Sdim      m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>(
233353358Sdim          *this, reg_interface, m_gpregset_data, m_notes);
234314564Sdim      break;
235314564Sdim    default:
236314564Sdim      break;
237314564Sdim    }
238262528Semaste
239314564Sdim    reg_ctx_sp = m_thread_reg_ctx_sp;
240341825Sdim  } else {
241341825Sdim    Unwind *unwinder = GetUnwinder();
242341825Sdim    if (unwinder != nullptr)
243341825Sdim      reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
244314564Sdim  }
245314564Sdim  return reg_ctx_sp;
246254721Semaste}
247254721Semaste
248314564Sdimbool ThreadElfCore::CalculateStopInfo() {
249314564Sdim  ProcessSP process_sp(GetProcess());
250314564Sdim  if (process_sp) {
251314564Sdim    SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo));
252314564Sdim    return true;
253314564Sdim  }
254314564Sdim  return false;
255254721Semaste}
256254721Semaste
257254721Semaste// Parse PRSTATUS from NOTE entry
258314564SdimELFLinuxPrStatus::ELFLinuxPrStatus() {
259314564Sdim  memset(this, 0, sizeof(ELFLinuxPrStatus));
260254721Semaste}
261254721Semaste
262327952Sdimsize_t ELFLinuxPrStatus::GetSize(const lldb_private::ArchSpec &arch) {
263321369Sdim  constexpr size_t mips_linux_pr_status_size_o32 = 96;
264321369Sdim  constexpr size_t mips_linux_pr_status_size_n32 = 72;
265353358Sdim  constexpr size_t num_ptr_size_members = 10;
266321369Sdim  if (arch.IsMIPS()) {
267321369Sdim    std::string abi = arch.GetTargetABI();
268321369Sdim    assert(!abi.empty() && "ABI is not set");
269321369Sdim    if (!abi.compare("n64"))
270321369Sdim      return sizeof(ELFLinuxPrStatus);
271321369Sdim    else if (!abi.compare("o32"))
272321369Sdim      return mips_linux_pr_status_size_o32;
273321369Sdim    // N32 ABI
274321369Sdim    return mips_linux_pr_status_size_n32;
275321369Sdim  }
276321369Sdim  switch (arch.GetCore()) {
277321369Sdim  case lldb_private::ArchSpec::eCore_x86_32_i386:
278321369Sdim  case lldb_private::ArchSpec::eCore_x86_32_i486:
279321369Sdim    return 72;
280321369Sdim  default:
281353358Sdim    if (arch.GetAddressByteSize() == 8)
282353358Sdim      return sizeof(ELFLinuxPrStatus);
283353358Sdim    else
284353358Sdim      return sizeof(ELFLinuxPrStatus) - num_ptr_size_members * 4;
285321369Sdim  }
286321369Sdim}
287321369Sdim
288327952SdimStatus ELFLinuxPrStatus::Parse(const DataExtractor &data,
289327952Sdim                               const ArchSpec &arch) {
290321369Sdim  Status error;
291314564Sdim  if (GetSize(arch) > data.GetByteSize()) {
292314564Sdim    error.SetErrorStringWithFormat(
293314564Sdim        "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64,
294314564Sdim        GetSize(arch), data.GetByteSize());
295314564Sdim    return error;
296314564Sdim  }
297314564Sdim
298341825Sdim  // Read field by field to correctly account for endianess of both the core
299341825Sdim  // dump and the platform running lldb.
300314564Sdim  offset_t offset = 0;
301314564Sdim  si_signo = data.GetU32(&offset);
302314564Sdim  si_code = data.GetU32(&offset);
303314564Sdim  si_errno = data.GetU32(&offset);
304314564Sdim
305314564Sdim  pr_cursig = data.GetU16(&offset);
306314564Sdim  offset += 2; // pad
307314564Sdim
308314564Sdim  pr_sigpend = data.GetPointer(&offset);
309314564Sdim  pr_sighold = data.GetPointer(&offset);
310314564Sdim
311314564Sdim  pr_pid = data.GetU32(&offset);
312314564Sdim  pr_ppid = data.GetU32(&offset);
313314564Sdim  pr_pgrp = data.GetU32(&offset);
314314564Sdim  pr_sid = data.GetU32(&offset);
315314564Sdim
316314564Sdim  pr_utime.tv_sec = data.GetPointer(&offset);
317314564Sdim  pr_utime.tv_usec = data.GetPointer(&offset);
318314564Sdim
319314564Sdim  pr_stime.tv_sec = data.GetPointer(&offset);
320314564Sdim  pr_stime.tv_usec = data.GetPointer(&offset);
321314564Sdim
322314564Sdim  pr_cutime.tv_sec = data.GetPointer(&offset);
323314564Sdim  pr_cutime.tv_usec = data.GetPointer(&offset);
324314564Sdim
325314564Sdim  pr_cstime.tv_sec = data.GetPointer(&offset);
326314564Sdim  pr_cstime.tv_usec = data.GetPointer(&offset);
327314564Sdim
328314564Sdim  return error;
329254721Semaste}
330254721Semaste
331254721Semaste// Parse PRPSINFO from NOTE entry
332314564SdimELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
333314564Sdim  memset(this, 0, sizeof(ELFLinuxPrPsInfo));
334254721Semaste}
335254721Semaste
336327952Sdimsize_t ELFLinuxPrPsInfo::GetSize(const lldb_private::ArchSpec &arch) {
337321369Sdim  constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128;
338321369Sdim  if (arch.IsMIPS()) {
339321369Sdim    uint8_t address_byte_size = arch.GetAddressByteSize();
340321369Sdim    if (address_byte_size == 8)
341321369Sdim      return sizeof(ELFLinuxPrPsInfo);
342321369Sdim    return mips_linux_pr_psinfo_size_o32_n32;
343321369Sdim  }
344341825Sdim
345321369Sdim  switch (arch.GetCore()) {
346321369Sdim  case lldb_private::ArchSpec::eCore_s390x_generic:
347321369Sdim  case lldb_private::ArchSpec::eCore_x86_64_x86_64:
348321369Sdim    return sizeof(ELFLinuxPrPsInfo);
349321369Sdim  case lldb_private::ArchSpec::eCore_x86_32_i386:
350321369Sdim  case lldb_private::ArchSpec::eCore_x86_32_i486:
351321369Sdim    return 124;
352321369Sdim  default:
353321369Sdim    return 0;
354321369Sdim  }
355321369Sdim}
356321369Sdim
357327952SdimStatus ELFLinuxPrPsInfo::Parse(const DataExtractor &data,
358327952Sdim                               const ArchSpec &arch) {
359321369Sdim  Status error;
360314564Sdim  ByteOrder byteorder = data.GetByteOrder();
361314564Sdim  if (GetSize(arch) > data.GetByteSize()) {
362314564Sdim    error.SetErrorStringWithFormat(
363314564Sdim        "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64,
364314564Sdim        GetSize(arch), data.GetByteSize());
365314564Sdim    return error;
366314564Sdim  }
367314564Sdim  size_t size = 0;
368314564Sdim  offset_t offset = 0;
369314564Sdim
370314564Sdim  pr_state = data.GetU8(&offset);
371314564Sdim  pr_sname = data.GetU8(&offset);
372314564Sdim  pr_zomb = data.GetU8(&offset);
373314564Sdim  pr_nice = data.GetU8(&offset);
374314564Sdim  if (data.GetAddressByteSize() == 8) {
375314564Sdim    // Word align the next field on 64 bit.
376314564Sdim    offset += 4;
377314564Sdim  }
378314564Sdim
379314564Sdim  pr_flag = data.GetPointer(&offset);
380314564Sdim
381321369Sdim  if (arch.IsMIPS()) {
382321369Sdim    // The pr_uid and pr_gid is always 32 bit irrespective of platforms
383321369Sdim    pr_uid = data.GetU32(&offset);
384321369Sdim    pr_gid = data.GetU32(&offset);
385321369Sdim  } else {
386341825Sdim    // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms
387341825Sdim    pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
388341825Sdim    pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
389321369Sdim  }
390314564Sdim
391314564Sdim  pr_pid = data.GetU32(&offset);
392314564Sdim  pr_ppid = data.GetU32(&offset);
393314564Sdim  pr_pgrp = data.GetU32(&offset);
394314564Sdim  pr_sid = data.GetU32(&offset);
395314564Sdim
396314564Sdim  size = 16;
397314564Sdim  data.ExtractBytes(offset, size, byteorder, pr_fname);
398314564Sdim  offset += size;
399314564Sdim
400314564Sdim  size = 80;
401314564Sdim  data.ExtractBytes(offset, size, byteorder, pr_psargs);
402314564Sdim  offset += size;
403314564Sdim
404314564Sdim  return error;
405254721Semaste}
406254721Semaste
407314564Sdim// Parse SIGINFO from NOTE entry
408321369SdimELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); }
409321369Sdim
410321369Sdimsize_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) {
411321369Sdim  if (arch.IsMIPS())
412321369Sdim    return sizeof(ELFLinuxSigInfo);
413321369Sdim  switch (arch.GetCore()) {
414321369Sdim  case lldb_private::ArchSpec::eCore_x86_64_x86_64:
415321369Sdim    return sizeof(ELFLinuxSigInfo);
416321369Sdim  case lldb_private::ArchSpec::eCore_s390x_generic:
417321369Sdim  case lldb_private::ArchSpec::eCore_x86_32_i386:
418321369Sdim  case lldb_private::ArchSpec::eCore_x86_32_i486:
419321369Sdim    return 12;
420321369Sdim  default:
421321369Sdim    return 0;
422321369Sdim  }
423314564Sdim}
424314564Sdim
425327952SdimStatus ELFLinuxSigInfo::Parse(const DataExtractor &data, const ArchSpec &arch) {
426321369Sdim  Status error;
427314564Sdim  if (GetSize(arch) > data.GetByteSize()) {
428314564Sdim    error.SetErrorStringWithFormat(
429314564Sdim        "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64,
430314564Sdim        GetSize(arch), data.GetByteSize());
431314564Sdim    return error;
432314564Sdim  }
433314564Sdim
434314564Sdim  // Parsing from a 32 bit ELF core file, and populating/reusing the structure
435314564Sdim  // properly, because the struct is for the 64 bit version
436314564Sdim  offset_t offset = 0;
437314564Sdim  si_signo = data.GetU32(&offset);
438314564Sdim  si_code = data.GetU32(&offset);
439314564Sdim  si_errno = data.GetU32(&offset);
440314564Sdim
441314564Sdim  return error;
442314564Sdim}
443