1*eee687a6SAndrej Korman //===-- ObjectFileMinidump.cpp --------------------------------------------===//
2*eee687a6SAndrej Korman //
3*eee687a6SAndrej Korman // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*eee687a6SAndrej Korman // See https://llvm.org/LICENSE.txt for license information.
5*eee687a6SAndrej Korman // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*eee687a6SAndrej Korman //
7*eee687a6SAndrej Korman //===----------------------------------------------------------------------===//
8*eee687a6SAndrej Korman 
9*eee687a6SAndrej Korman #include "ObjectFileMinidump.h"
10*eee687a6SAndrej Korman 
11*eee687a6SAndrej Korman #include "MinidumpFileBuilder.h"
12*eee687a6SAndrej Korman 
13*eee687a6SAndrej Korman #include "lldb/Core/ModuleSpec.h"
14*eee687a6SAndrej Korman #include "lldb/Core/PluginManager.h"
15*eee687a6SAndrej Korman #include "lldb/Core/Section.h"
16*eee687a6SAndrej Korman #include "lldb/Target/Process.h"
17*eee687a6SAndrej Korman 
18*eee687a6SAndrej Korman #include "llvm/Support/FileSystem.h"
19*eee687a6SAndrej Korman 
20*eee687a6SAndrej Korman using namespace lldb;
21*eee687a6SAndrej Korman using namespace lldb_private;
22*eee687a6SAndrej Korman 
23*eee687a6SAndrej Korman LLDB_PLUGIN_DEFINE(ObjectFileMinidump)
24*eee687a6SAndrej Korman 
25*eee687a6SAndrej Korman void ObjectFileMinidump::Initialize() {
26*eee687a6SAndrej Korman   PluginManager::RegisterPlugin(
27*eee687a6SAndrej Korman       GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
28*eee687a6SAndrej Korman       CreateMemoryInstance, GetModuleSpecifications, SaveCore);
29*eee687a6SAndrej Korman }
30*eee687a6SAndrej Korman 
31*eee687a6SAndrej Korman void ObjectFileMinidump::Terminate() {
32*eee687a6SAndrej Korman   PluginManager::UnregisterPlugin(CreateInstance);
33*eee687a6SAndrej Korman }
34*eee687a6SAndrej Korman 
35*eee687a6SAndrej Korman ConstString ObjectFileMinidump::GetPluginNameStatic() {
36*eee687a6SAndrej Korman   static ConstString g_name("minidump");
37*eee687a6SAndrej Korman   return g_name;
38*eee687a6SAndrej Korman }
39*eee687a6SAndrej Korman 
40*eee687a6SAndrej Korman ObjectFile *ObjectFileMinidump::CreateInstance(
41*eee687a6SAndrej Korman     const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
42*eee687a6SAndrej Korman     lldb::offset_t data_offset, const lldb_private::FileSpec *file,
43*eee687a6SAndrej Korman     lldb::offset_t offset, lldb::offset_t length) {
44*eee687a6SAndrej Korman   return nullptr;
45*eee687a6SAndrej Korman }
46*eee687a6SAndrej Korman 
47*eee687a6SAndrej Korman ObjectFile *ObjectFileMinidump::CreateMemoryInstance(
48*eee687a6SAndrej Korman     const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
49*eee687a6SAndrej Korman     const ProcessSP &process_sp, lldb::addr_t header_addr) {
50*eee687a6SAndrej Korman   return nullptr;
51*eee687a6SAndrej Korman }
52*eee687a6SAndrej Korman 
53*eee687a6SAndrej Korman size_t ObjectFileMinidump::GetModuleSpecifications(
54*eee687a6SAndrej Korman     const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
55*eee687a6SAndrej Korman     lldb::offset_t data_offset, lldb::offset_t file_offset,
56*eee687a6SAndrej Korman     lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
57*eee687a6SAndrej Korman   specs.Clear();
58*eee687a6SAndrej Korman   return 0;
59*eee687a6SAndrej Korman }
60*eee687a6SAndrej Korman 
61*eee687a6SAndrej Korman bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp,
62*eee687a6SAndrej Korman                                   const lldb_private::FileSpec &outfile,
63*eee687a6SAndrej Korman                                   lldb::SaveCoreStyle &core_style,
64*eee687a6SAndrej Korman                                   lldb_private::Status &error) {
65*eee687a6SAndrej Korman   if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
66*eee687a6SAndrej Korman     error.SetErrorString("Only stack minidumps supported yet.");
67*eee687a6SAndrej Korman     return false;
68*eee687a6SAndrej Korman   }
69*eee687a6SAndrej Korman 
70*eee687a6SAndrej Korman   if (!process_sp)
71*eee687a6SAndrej Korman     return false;
72*eee687a6SAndrej Korman 
73*eee687a6SAndrej Korman   MinidumpFileBuilder builder;
74*eee687a6SAndrej Korman 
75*eee687a6SAndrej Korman   Target &target = process_sp->GetTarget();
76*eee687a6SAndrej Korman 
77*eee687a6SAndrej Korman   error = builder.AddSystemInfo(target.GetArchitecture().GetTriple());
78*eee687a6SAndrej Korman   if (error.Fail())
79*eee687a6SAndrej Korman     return false;
80*eee687a6SAndrej Korman 
81*eee687a6SAndrej Korman   error = builder.AddModuleList(target);
82*eee687a6SAndrej Korman   if (error.Fail())
83*eee687a6SAndrej Korman     return false;
84*eee687a6SAndrej Korman 
85*eee687a6SAndrej Korman   builder.AddMiscInfo(process_sp);
86*eee687a6SAndrej Korman 
87*eee687a6SAndrej Korman   if (target.GetArchitecture().GetMachine() == llvm::Triple::ArchType::x86_64) {
88*eee687a6SAndrej Korman     error = builder.AddThreadList(process_sp);
89*eee687a6SAndrej Korman     if (error.Fail())
90*eee687a6SAndrej Korman       return false;
91*eee687a6SAndrej Korman 
92*eee687a6SAndrej Korman     error = builder.AddException(process_sp);
93*eee687a6SAndrej Korman     if (error.Fail())
94*eee687a6SAndrej Korman       return false;
95*eee687a6SAndrej Korman 
96*eee687a6SAndrej Korman     error = builder.AddMemoryList(process_sp);
97*eee687a6SAndrej Korman     if (error.Fail())
98*eee687a6SAndrej Korman       return false;
99*eee687a6SAndrej Korman   }
100*eee687a6SAndrej Korman 
101*eee687a6SAndrej Korman   if (target.GetArchitecture().GetTriple().getOS() ==
102*eee687a6SAndrej Korman       llvm::Triple::OSType::Linux) {
103*eee687a6SAndrej Korman     builder.AddLinuxFileStreams(process_sp);
104*eee687a6SAndrej Korman   }
105*eee687a6SAndrej Korman 
106*eee687a6SAndrej Korman   llvm::Expected<lldb::FileUP> maybe_core_file = FileSystem::Instance().Open(
107*eee687a6SAndrej Korman       outfile, File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate);
108*eee687a6SAndrej Korman   if (!maybe_core_file) {
109*eee687a6SAndrej Korman     error = maybe_core_file.takeError();
110*eee687a6SAndrej Korman     return false;
111*eee687a6SAndrej Korman   }
112*eee687a6SAndrej Korman   lldb::FileUP core_file = std::move(maybe_core_file.get());
113*eee687a6SAndrej Korman 
114*eee687a6SAndrej Korman   error = builder.Dump(core_file);
115*eee687a6SAndrej Korman   if (error.Fail())
116*eee687a6SAndrej Korman     return false;
117*eee687a6SAndrej Korman 
118*eee687a6SAndrej Korman   return true;
119*eee687a6SAndrej Korman }
120