xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1349cc55cSDimitry Andric //===-- ObjectFileMinidump.cpp --------------------------------------------===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric 
9349cc55cSDimitry Andric #include "ObjectFileMinidump.h"
10349cc55cSDimitry Andric 
11349cc55cSDimitry Andric #include "MinidumpFileBuilder.h"
12349cc55cSDimitry Andric 
13349cc55cSDimitry Andric #include "lldb/Core/ModuleSpec.h"
14349cc55cSDimitry Andric #include "lldb/Core/PluginManager.h"
15349cc55cSDimitry Andric #include "lldb/Core/Section.h"
16349cc55cSDimitry Andric #include "lldb/Target/Process.h"
17*0fca6ea1SDimitry Andric #include "lldb/Utility/LLDBLog.h"
18*0fca6ea1SDimitry Andric #include "lldb/Utility/Log.h"
19349cc55cSDimitry Andric 
20349cc55cSDimitry Andric #include "llvm/Support/FileSystem.h"
21349cc55cSDimitry Andric 
22349cc55cSDimitry Andric using namespace lldb;
23349cc55cSDimitry Andric using namespace lldb_private;
24349cc55cSDimitry Andric 
25349cc55cSDimitry Andric LLDB_PLUGIN_DEFINE(ObjectFileMinidump)
26349cc55cSDimitry Andric 
27349cc55cSDimitry Andric void ObjectFileMinidump::Initialize() {
28349cc55cSDimitry Andric   PluginManager::RegisterPlugin(
29349cc55cSDimitry Andric       GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
30349cc55cSDimitry Andric       CreateMemoryInstance, GetModuleSpecifications, SaveCore);
31349cc55cSDimitry Andric }
32349cc55cSDimitry Andric 
33349cc55cSDimitry Andric void ObjectFileMinidump::Terminate() {
34349cc55cSDimitry Andric   PluginManager::UnregisterPlugin(CreateInstance);
35349cc55cSDimitry Andric }
36349cc55cSDimitry Andric 
37349cc55cSDimitry Andric ObjectFile *ObjectFileMinidump::CreateInstance(
3881ad6265SDimitry Andric     const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
39349cc55cSDimitry Andric     lldb::offset_t data_offset, const lldb_private::FileSpec *file,
40349cc55cSDimitry Andric     lldb::offset_t offset, lldb::offset_t length) {
41349cc55cSDimitry Andric   return nullptr;
42349cc55cSDimitry Andric }
43349cc55cSDimitry Andric 
44349cc55cSDimitry Andric ObjectFile *ObjectFileMinidump::CreateMemoryInstance(
4581ad6265SDimitry Andric     const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
46349cc55cSDimitry Andric     const ProcessSP &process_sp, lldb::addr_t header_addr) {
47349cc55cSDimitry Andric   return nullptr;
48349cc55cSDimitry Andric }
49349cc55cSDimitry Andric 
50349cc55cSDimitry Andric size_t ObjectFileMinidump::GetModuleSpecifications(
51349cc55cSDimitry Andric     const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
52349cc55cSDimitry Andric     lldb::offset_t data_offset, lldb::offset_t file_offset,
53349cc55cSDimitry Andric     lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
54349cc55cSDimitry Andric   specs.Clear();
55349cc55cSDimitry Andric   return 0;
56349cc55cSDimitry Andric }
57349cc55cSDimitry Andric 
58349cc55cSDimitry Andric bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp,
59*0fca6ea1SDimitry Andric                                   const lldb_private::SaveCoreOptions &options,
60349cc55cSDimitry Andric                                   lldb_private::Status &error) {
61*0fca6ea1SDimitry Andric   // Output file and process_sp are both checked in PluginManager::SaveCore.
62*0fca6ea1SDimitry Andric   assert(options.GetOutputFile().has_value());
63*0fca6ea1SDimitry Andric   assert(process_sp);
64*0fca6ea1SDimitry Andric 
65*0fca6ea1SDimitry Andric   // Minidump defaults to stacks only.
66*0fca6ea1SDimitry Andric   SaveCoreStyle core_style = options.GetStyle();
675f757f3fSDimitry Andric   if (core_style == SaveCoreStyle::eSaveCoreUnspecified)
685f757f3fSDimitry Andric     core_style = SaveCoreStyle::eSaveCoreStackOnly;
69349cc55cSDimitry Andric 
70349cc55cSDimitry Andric   llvm::Expected<lldb::FileUP> maybe_core_file = FileSystem::Instance().Open(
71*0fca6ea1SDimitry Andric       options.GetOutputFile().value(),
72*0fca6ea1SDimitry Andric       File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate);
73349cc55cSDimitry Andric   if (!maybe_core_file) {
74349cc55cSDimitry Andric     error = maybe_core_file.takeError();
75349cc55cSDimitry Andric     return false;
76349cc55cSDimitry Andric   }
77*0fca6ea1SDimitry Andric   MinidumpFileBuilder builder(std::move(maybe_core_file.get()), process_sp);
78349cc55cSDimitry Andric 
79*0fca6ea1SDimitry Andric   Log *log = GetLog(LLDBLog::Object);
80*0fca6ea1SDimitry Andric   error = builder.AddHeaderAndCalculateDirectories();
81*0fca6ea1SDimitry Andric   if (error.Fail()) {
82*0fca6ea1SDimitry Andric     LLDB_LOGF(log, "AddHeaderAndCalculateDirectories failed: %s",
83*0fca6ea1SDimitry Andric               error.AsCString());
84349cc55cSDimitry Andric     return false;
85*0fca6ea1SDimitry Andric   };
86*0fca6ea1SDimitry Andric   error = builder.AddSystemInfo();
87*0fca6ea1SDimitry Andric   if (error.Fail()) {
88*0fca6ea1SDimitry Andric     LLDB_LOGF(log, "AddSystemInfo failed: %s", error.AsCString());
89*0fca6ea1SDimitry Andric     return false;
90*0fca6ea1SDimitry Andric   }
91*0fca6ea1SDimitry Andric 
92*0fca6ea1SDimitry Andric   error = builder.AddModuleList();
93*0fca6ea1SDimitry Andric   if (error.Fail()) {
94*0fca6ea1SDimitry Andric     LLDB_LOGF(log, "AddModuleList failed: %s", error.AsCString());
95*0fca6ea1SDimitry Andric     return false;
96*0fca6ea1SDimitry Andric   }
97*0fca6ea1SDimitry Andric   error = builder.AddMiscInfo();
98*0fca6ea1SDimitry Andric   if (error.Fail()) {
99*0fca6ea1SDimitry Andric     LLDB_LOGF(log, "AddMiscInfo failed: %s", error.AsCString());
100*0fca6ea1SDimitry Andric     return false;
101*0fca6ea1SDimitry Andric   }
102*0fca6ea1SDimitry Andric 
103*0fca6ea1SDimitry Andric   error = builder.AddThreadList();
104*0fca6ea1SDimitry Andric   if (error.Fail()) {
105*0fca6ea1SDimitry Andric     LLDB_LOGF(log, "AddThreadList failed: %s", error.AsCString());
106*0fca6ea1SDimitry Andric     return false;
107*0fca6ea1SDimitry Andric   }
108*0fca6ea1SDimitry Andric 
109*0fca6ea1SDimitry Andric   error = builder.AddLinuxFileStreams();
110*0fca6ea1SDimitry Andric   if (error.Fail()) {
111*0fca6ea1SDimitry Andric     LLDB_LOGF(log, "AddLinuxFileStreams failed: %s", error.AsCString());
112*0fca6ea1SDimitry Andric     return false;
113*0fca6ea1SDimitry Andric   }
114*0fca6ea1SDimitry Andric 
115*0fca6ea1SDimitry Andric   // Add any exceptions but only if there are any in any threads.
116*0fca6ea1SDimitry Andric   error = builder.AddExceptions();
117*0fca6ea1SDimitry Andric   if (error.Fail()) {
118*0fca6ea1SDimitry Andric     LLDB_LOGF(log, "AddExceptions failed: %s", error.AsCString());
119*0fca6ea1SDimitry Andric     return false;
120*0fca6ea1SDimitry Andric   }
121*0fca6ea1SDimitry Andric 
122*0fca6ea1SDimitry Andric   // Note: add memory HAS to be the last thing we do. It can overflow into 64b
123*0fca6ea1SDimitry Andric   // land and many RVA's only support 32b
124*0fca6ea1SDimitry Andric   error = builder.AddMemoryList(core_style);
125*0fca6ea1SDimitry Andric   if (error.Fail()) {
126*0fca6ea1SDimitry Andric     LLDB_LOGF(log, "AddMemoryList failed: %s", error.AsCString());
127*0fca6ea1SDimitry Andric     return false;
128*0fca6ea1SDimitry Andric   }
129*0fca6ea1SDimitry Andric 
130*0fca6ea1SDimitry Andric   error = builder.DumpFile();
131*0fca6ea1SDimitry Andric   if (error.Fail()) {
132*0fca6ea1SDimitry Andric     LLDB_LOGF(log, "DumpFile failed: %s", error.AsCString());
133*0fca6ea1SDimitry Andric     return false;
134*0fca6ea1SDimitry Andric   }
135349cc55cSDimitry Andric 
136349cc55cSDimitry Andric   return true;
137349cc55cSDimitry Andric }
138