ThreadMinidump.cpp revision 360660
1//===-- ThreadMinidump.cpp --------------------------------------*- 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#include "ThreadMinidump.h"
10
11#include "ProcessMinidump.h"
12
13#include "RegisterContextMinidump_ARM.h"
14#include "RegisterContextMinidump_ARM64.h"
15#include "RegisterContextMinidump_x86_32.h"
16#include "RegisterContextMinidump_x86_64.h"
17
18#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
19#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
20#include "Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h"
21#include "Plugins/Process/elf-core/RegisterUtilities.h"
22
23#include "lldb/Target/RegisterContext.h"
24#include "lldb/Target/StopInfo.h"
25#include "lldb/Target/Target.h"
26#include "lldb/Target/Unwind.h"
27#include "lldb/Utility/DataExtractor.h"
28#include "lldb/Utility/Log.h"
29
30#include <memory>
31
32using namespace lldb;
33using namespace lldb_private;
34using namespace minidump;
35
36ThreadMinidump::ThreadMinidump(Process &process, const minidump::Thread &td,
37                               llvm::ArrayRef<uint8_t> gpregset_data)
38    : Thread(process, td.ThreadId), m_thread_reg_ctx_sp(),
39      m_gpregset_data(gpregset_data) {}
40
41ThreadMinidump::~ThreadMinidump() {}
42
43void ThreadMinidump::RefreshStateAfterStop() {}
44
45RegisterContextSP ThreadMinidump::GetRegisterContext() {
46  if (!m_reg_context_sp) {
47    m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
48  }
49  return m_reg_context_sp;
50}
51
52RegisterContextSP
53ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) {
54  RegisterContextSP reg_ctx_sp;
55  uint32_t concrete_frame_idx = 0;
56
57  if (frame)
58    concrete_frame_idx = frame->GetConcreteFrameIndex();
59
60  if (concrete_frame_idx == 0) {
61    if (m_thread_reg_ctx_sp)
62      return m_thread_reg_ctx_sp;
63
64    ProcessMinidump *process =
65        static_cast<ProcessMinidump *>(GetProcess().get());
66    ArchSpec arch = process->GetArchitecture();
67    RegisterInfoInterface *reg_interface = nullptr;
68
69    // TODO write other register contexts and add them here
70    switch (arch.GetMachine()) {
71    case llvm::Triple::x86: {
72      reg_interface = new RegisterContextLinux_i386(arch);
73      lldb::DataBufferSP buf =
74          ConvertMinidumpContext_x86_32(m_gpregset_data, reg_interface);
75      DataExtractor gpregset(buf, lldb::eByteOrderLittle, 4);
76      m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>(
77          *this, reg_interface, gpregset,
78          llvm::ArrayRef<lldb_private::CoreNote>());
79      break;
80    }
81    case llvm::Triple::x86_64: {
82      reg_interface = new RegisterContextLinux_x86_64(arch);
83      lldb::DataBufferSP buf =
84          ConvertMinidumpContext_x86_64(m_gpregset_data, reg_interface);
85      DataExtractor gpregset(buf, lldb::eByteOrderLittle, 8);
86      m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>(
87          *this, reg_interface, gpregset,
88          llvm::ArrayRef<lldb_private::CoreNote>());
89      break;
90    }
91    case llvm::Triple::aarch64: {
92      DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(),
93                         lldb::eByteOrderLittle, 8);
94      m_thread_reg_ctx_sp =
95          std::make_shared<RegisterContextMinidump_ARM64>(*this, data);
96      break;
97    }
98    case llvm::Triple::arm: {
99      DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(),
100                         lldb::eByteOrderLittle, 8);
101      const bool apple = arch.GetTriple().getVendor() == llvm::Triple::Apple;
102      m_thread_reg_ctx_sp =
103          std::make_shared<RegisterContextMinidump_ARM>(*this, data, apple);
104      break;
105    }
106    default:
107      break;
108    }
109
110    reg_ctx_sp = m_thread_reg_ctx_sp;
111  } else if (m_unwinder_up) {
112    reg_ctx_sp = m_unwinder_up->CreateRegisterContextForFrame(frame);
113  }
114
115  return reg_ctx_sp;
116}
117
118bool ThreadMinidump::CalculateStopInfo() { return false; }
119