180814287SRaphael Isemann //===-- ThreadMinidump.cpp ------------------------------------------------===//
27b18dd4fSDimitar Vlahovski //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67b18dd4fSDimitar Vlahovski //
77b18dd4fSDimitar Vlahovski //===----------------------------------------------------------------------===//
87b18dd4fSDimitar Vlahovski 
97b18dd4fSDimitar Vlahovski #include "ThreadMinidump.h"
10796ac80bSJonas Devlieghere 
117b18dd4fSDimitar Vlahovski #include "ProcessMinidump.h"
127b18dd4fSDimitar Vlahovski 
1319c8f394SGreg Clayton #include "RegisterContextMinidump_ARM.h"
1419c8f394SGreg Clayton #include "RegisterContextMinidump_ARM64.h"
157b18dd4fSDimitar Vlahovski #include "RegisterContextMinidump_x86_32.h"
167b18dd4fSDimitar Vlahovski #include "RegisterContextMinidump_x86_64.h"
177b18dd4fSDimitar Vlahovski 
187b18dd4fSDimitar Vlahovski #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
197b18dd4fSDimitar Vlahovski #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
207b18dd4fSDimitar Vlahovski #include "Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h"
21bc8cc867SPavel Labath #include "Plugins/Process/elf-core/RegisterUtilities.h"
227b18dd4fSDimitar Vlahovski 
237b18dd4fSDimitar Vlahovski #include "lldb/Target/RegisterContext.h"
247b18dd4fSDimitar Vlahovski #include "lldb/Target/StopInfo.h"
257b18dd4fSDimitar Vlahovski #include "lldb/Target/Target.h"
267b18dd4fSDimitar Vlahovski #include "lldb/Target/Unwind.h"
27666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h"
286f9e6901SZachary Turner #include "lldb/Utility/Log.h"
297b18dd4fSDimitar Vlahovski 
30796ac80bSJonas Devlieghere #include <memory>
317b18dd4fSDimitar Vlahovski 
327b18dd4fSDimitar Vlahovski using namespace lldb;
337b18dd4fSDimitar Vlahovski using namespace lldb_private;
347b18dd4fSDimitar Vlahovski using namespace minidump;
357b18dd4fSDimitar Vlahovski 
ThreadMinidump(Process & process,const minidump::Thread & td,llvm::ArrayRef<uint8_t> gpregset_data)366d40c29aSPavel Labath ThreadMinidump::ThreadMinidump(Process &process, const minidump::Thread &td,
377b18dd4fSDimitar Vlahovski                                llvm::ArrayRef<uint8_t> gpregset_data)
386d40c29aSPavel Labath     : Thread(process, td.ThreadId), m_thread_reg_ctx_sp(),
397b18dd4fSDimitar Vlahovski       m_gpregset_data(gpregset_data) {}
407b18dd4fSDimitar Vlahovski 
41*fd2433e1SJonas Devlieghere ThreadMinidump::~ThreadMinidump() = default;
427b18dd4fSDimitar Vlahovski 
RefreshStateAfterStop()437b18dd4fSDimitar Vlahovski void ThreadMinidump::RefreshStateAfterStop() {}
447b18dd4fSDimitar Vlahovski 
GetRegisterContext()457b18dd4fSDimitar Vlahovski RegisterContextSP ThreadMinidump::GetRegisterContext() {
467b18dd4fSDimitar Vlahovski   if (!m_reg_context_sp) {
477b18dd4fSDimitar Vlahovski     m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
487b18dd4fSDimitar Vlahovski   }
497b18dd4fSDimitar Vlahovski   return m_reg_context_sp;
507b18dd4fSDimitar Vlahovski }
517b18dd4fSDimitar Vlahovski 
527b18dd4fSDimitar Vlahovski RegisterContextSP
CreateRegisterContextForFrame(StackFrame * frame)537b18dd4fSDimitar Vlahovski ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) {
547b18dd4fSDimitar Vlahovski   RegisterContextSP reg_ctx_sp;
557b18dd4fSDimitar Vlahovski   uint32_t concrete_frame_idx = 0;
567b18dd4fSDimitar Vlahovski 
577b18dd4fSDimitar Vlahovski   if (frame)
587b18dd4fSDimitar Vlahovski     concrete_frame_idx = frame->GetConcreteFrameIndex();
597b18dd4fSDimitar Vlahovski 
607b18dd4fSDimitar Vlahovski   if (concrete_frame_idx == 0) {
617b18dd4fSDimitar Vlahovski     if (m_thread_reg_ctx_sp)
627b18dd4fSDimitar Vlahovski       return m_thread_reg_ctx_sp;
637b18dd4fSDimitar Vlahovski 
647b18dd4fSDimitar Vlahovski     ProcessMinidump *process =
657b18dd4fSDimitar Vlahovski         static_cast<ProcessMinidump *>(GetProcess().get());
667b18dd4fSDimitar Vlahovski     ArchSpec arch = process->GetArchitecture();
677b18dd4fSDimitar Vlahovski     RegisterInfoInterface *reg_interface = nullptr;
687b18dd4fSDimitar Vlahovski 
697b18dd4fSDimitar Vlahovski     // TODO write other register contexts and add them here
707b18dd4fSDimitar Vlahovski     switch (arch.GetMachine()) {
717b18dd4fSDimitar Vlahovski     case llvm::Triple::x86: {
727b18dd4fSDimitar Vlahovski       reg_interface = new RegisterContextLinux_i386(arch);
737b18dd4fSDimitar Vlahovski       lldb::DataBufferSP buf =
747b18dd4fSDimitar Vlahovski           ConvertMinidumpContext_x86_32(m_gpregset_data, reg_interface);
75bc8cc867SPavel Labath       DataExtractor gpregset(buf, lldb::eByteOrderLittle, 4);
76796ac80bSJonas Devlieghere       m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>(
77796ac80bSJonas Devlieghere           *this, reg_interface, gpregset,
78796ac80bSJonas Devlieghere           llvm::ArrayRef<lldb_private::CoreNote>());
797b18dd4fSDimitar Vlahovski       break;
807b18dd4fSDimitar Vlahovski     }
817b18dd4fSDimitar Vlahovski     case llvm::Triple::x86_64: {
827b18dd4fSDimitar Vlahovski       reg_interface = new RegisterContextLinux_x86_64(arch);
837b18dd4fSDimitar Vlahovski       lldb::DataBufferSP buf =
847b18dd4fSDimitar Vlahovski           ConvertMinidumpContext_x86_64(m_gpregset_data, reg_interface);
85bc8cc867SPavel Labath       DataExtractor gpregset(buf, lldb::eByteOrderLittle, 8);
86796ac80bSJonas Devlieghere       m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>(
87796ac80bSJonas Devlieghere           *this, reg_interface, gpregset,
88796ac80bSJonas Devlieghere           llvm::ArrayRef<lldb_private::CoreNote>());
897b18dd4fSDimitar Vlahovski       break;
907b18dd4fSDimitar Vlahovski     }
9119c8f394SGreg Clayton     case llvm::Triple::aarch64: {
9219c8f394SGreg Clayton       DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(),
9319c8f394SGreg Clayton                          lldb::eByteOrderLittle, 8);
94796ac80bSJonas Devlieghere       m_thread_reg_ctx_sp =
95796ac80bSJonas Devlieghere           std::make_shared<RegisterContextMinidump_ARM64>(*this, data);
962d953f22SGreg Clayton       break;
977b18dd4fSDimitar Vlahovski     }
9819c8f394SGreg Clayton     case llvm::Triple::arm: {
9919c8f394SGreg Clayton       DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(),
10019c8f394SGreg Clayton                          lldb::eByteOrderLittle, 8);
10119c8f394SGreg Clayton       const bool apple = arch.GetTriple().getVendor() == llvm::Triple::Apple;
102796ac80bSJonas Devlieghere       m_thread_reg_ctx_sp =
103796ac80bSJonas Devlieghere           std::make_shared<RegisterContextMinidump_ARM>(*this, data, apple);
10419c8f394SGreg Clayton       break;
10519c8f394SGreg Clayton     }
10619c8f394SGreg Clayton     default:
10719c8f394SGreg Clayton       break;
108659cee52SPavel Labath     }
109659cee52SPavel Labath 
1107b18dd4fSDimitar Vlahovski     reg_ctx_sp = m_thread_reg_ctx_sp;
111d5b44036SJonas Devlieghere   } else if (m_unwinder_up) {
112d5b44036SJonas Devlieghere     reg_ctx_sp = m_unwinder_up->CreateRegisterContextForFrame(frame);
1137b18dd4fSDimitar Vlahovski   }
1147b18dd4fSDimitar Vlahovski 
1157b18dd4fSDimitar Vlahovski   return reg_ctx_sp;
1167b18dd4fSDimitar Vlahovski }
1177b18dd4fSDimitar Vlahovski 
CalculateStopInfo()1187b18dd4fSDimitar Vlahovski bool ThreadMinidump::CalculateStopInfo() { return false; }
119