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