1//===-- ThreadMinidump.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
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() = default;
42
43void ThreadMinidump::RefreshStateAfterStop() {}
44
45RegisterContextSP ThreadMinidump::GetRegisterContext() {
46 if (!m_reg_context_sp) {
47 m_reg_context_sp = CreateRegisterContextForFrame(frame: 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(source_data: m_gpregset_data, target_reg_interface: reg_interface);
75 DataExtractor gpregset(buf, lldb::eByteOrderLittle, 4);
76 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>(
77 args&: *this, args&: reg_interface, args&: gpregset,
78 args: 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(source_data: m_gpregset_data, target_reg_interface: reg_interface);
85 DataExtractor gpregset(buf, lldb::eByteOrderLittle, 8);
86 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>(
87 args&: *this, args&: reg_interface, args&: gpregset,
88 args: 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>(args&: *this, args&: 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>(args&: *this, args&: data, args: 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

source code of lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp