xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp (revision be691f3bb6417f04a68938fadbcaee2d5795e764)
1dda28197Spatrick //===-- ThreadMinidump.cpp ------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "ThreadMinidump.h"
10061da546Spatrick 
11061da546Spatrick #include "ProcessMinidump.h"
12061da546Spatrick 
13061da546Spatrick #include "RegisterContextMinidump_ARM.h"
14061da546Spatrick #include "RegisterContextMinidump_ARM64.h"
15061da546Spatrick #include "RegisterContextMinidump_x86_32.h"
16061da546Spatrick #include "RegisterContextMinidump_x86_64.h"
17061da546Spatrick 
18061da546Spatrick #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
19061da546Spatrick #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
20061da546Spatrick #include "Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h"
21061da546Spatrick #include "Plugins/Process/elf-core/RegisterUtilities.h"
22061da546Spatrick 
23061da546Spatrick #include "lldb/Target/RegisterContext.h"
24061da546Spatrick #include "lldb/Target/StopInfo.h"
25061da546Spatrick #include "lldb/Target/Target.h"
26061da546Spatrick #include "lldb/Target/Unwind.h"
27061da546Spatrick #include "lldb/Utility/DataExtractor.h"
28061da546Spatrick #include "lldb/Utility/Log.h"
29061da546Spatrick 
30061da546Spatrick #include <memory>
31061da546Spatrick 
32061da546Spatrick using namespace lldb;
33061da546Spatrick using namespace lldb_private;
34061da546Spatrick using namespace minidump;
35061da546Spatrick 
ThreadMinidump(Process & process,const minidump::Thread & td,llvm::ArrayRef<uint8_t> gpregset_data)36061da546Spatrick ThreadMinidump::ThreadMinidump(Process &process, const minidump::Thread &td,
37061da546Spatrick                                llvm::ArrayRef<uint8_t> gpregset_data)
38061da546Spatrick     : Thread(process, td.ThreadId), m_thread_reg_ctx_sp(),
39061da546Spatrick       m_gpregset_data(gpregset_data) {}
40061da546Spatrick 
41*be691f3bSpatrick ThreadMinidump::~ThreadMinidump() = default;
42061da546Spatrick 
RefreshStateAfterStop()43061da546Spatrick void ThreadMinidump::RefreshStateAfterStop() {}
44061da546Spatrick 
GetRegisterContext()45061da546Spatrick RegisterContextSP ThreadMinidump::GetRegisterContext() {
46061da546Spatrick   if (!m_reg_context_sp) {
47061da546Spatrick     m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
48061da546Spatrick   }
49061da546Spatrick   return m_reg_context_sp;
50061da546Spatrick }
51061da546Spatrick 
52061da546Spatrick RegisterContextSP
CreateRegisterContextForFrame(StackFrame * frame)53061da546Spatrick ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) {
54061da546Spatrick   RegisterContextSP reg_ctx_sp;
55061da546Spatrick   uint32_t concrete_frame_idx = 0;
56061da546Spatrick 
57061da546Spatrick   if (frame)
58061da546Spatrick     concrete_frame_idx = frame->GetConcreteFrameIndex();
59061da546Spatrick 
60061da546Spatrick   if (concrete_frame_idx == 0) {
61061da546Spatrick     if (m_thread_reg_ctx_sp)
62061da546Spatrick       return m_thread_reg_ctx_sp;
63061da546Spatrick 
64061da546Spatrick     ProcessMinidump *process =
65061da546Spatrick         static_cast<ProcessMinidump *>(GetProcess().get());
66061da546Spatrick     ArchSpec arch = process->GetArchitecture();
67061da546Spatrick     RegisterInfoInterface *reg_interface = nullptr;
68061da546Spatrick 
69061da546Spatrick     // TODO write other register contexts and add them here
70061da546Spatrick     switch (arch.GetMachine()) {
71061da546Spatrick     case llvm::Triple::x86: {
72061da546Spatrick       reg_interface = new RegisterContextLinux_i386(arch);
73061da546Spatrick       lldb::DataBufferSP buf =
74061da546Spatrick           ConvertMinidumpContext_x86_32(m_gpregset_data, reg_interface);
75061da546Spatrick       DataExtractor gpregset(buf, lldb::eByteOrderLittle, 4);
76061da546Spatrick       m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>(
77061da546Spatrick           *this, reg_interface, gpregset,
78061da546Spatrick           llvm::ArrayRef<lldb_private::CoreNote>());
79061da546Spatrick       break;
80061da546Spatrick     }
81061da546Spatrick     case llvm::Triple::x86_64: {
82061da546Spatrick       reg_interface = new RegisterContextLinux_x86_64(arch);
83061da546Spatrick       lldb::DataBufferSP buf =
84061da546Spatrick           ConvertMinidumpContext_x86_64(m_gpregset_data, reg_interface);
85061da546Spatrick       DataExtractor gpregset(buf, lldb::eByteOrderLittle, 8);
86061da546Spatrick       m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>(
87061da546Spatrick           *this, reg_interface, gpregset,
88061da546Spatrick           llvm::ArrayRef<lldb_private::CoreNote>());
89061da546Spatrick       break;
90061da546Spatrick     }
91061da546Spatrick     case llvm::Triple::aarch64: {
92061da546Spatrick       DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(),
93061da546Spatrick                          lldb::eByteOrderLittle, 8);
94061da546Spatrick       m_thread_reg_ctx_sp =
95061da546Spatrick           std::make_shared<RegisterContextMinidump_ARM64>(*this, data);
96061da546Spatrick       break;
97061da546Spatrick     }
98061da546Spatrick     case llvm::Triple::arm: {
99061da546Spatrick       DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(),
100061da546Spatrick                          lldb::eByteOrderLittle, 8);
101061da546Spatrick       const bool apple = arch.GetTriple().getVendor() == llvm::Triple::Apple;
102061da546Spatrick       m_thread_reg_ctx_sp =
103061da546Spatrick           std::make_shared<RegisterContextMinidump_ARM>(*this, data, apple);
104061da546Spatrick       break;
105061da546Spatrick     }
106061da546Spatrick     default:
107061da546Spatrick       break;
108061da546Spatrick     }
109061da546Spatrick 
110061da546Spatrick     reg_ctx_sp = m_thread_reg_ctx_sp;
111061da546Spatrick   } else if (m_unwinder_up) {
112061da546Spatrick     reg_ctx_sp = m_unwinder_up->CreateRegisterContextForFrame(frame);
113061da546Spatrick   }
114061da546Spatrick 
115061da546Spatrick   return reg_ctx_sp;
116061da546Spatrick }
117061da546Spatrick 
CalculateStopInfo()118061da546Spatrick bool ThreadMinidump::CalculateStopInfo() { return false; }
119