xref: /src/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1c0981da4SDimitry Andric //===-- ObjectFileMinidump.cpp --------------------------------------------===//
2c0981da4SDimitry Andric //
3c0981da4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c0981da4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5c0981da4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c0981da4SDimitry Andric //
7c0981da4SDimitry Andric //===----------------------------------------------------------------------===//
8c0981da4SDimitry Andric 
9c0981da4SDimitry Andric #include "ObjectFileMinidump.h"
10c0981da4SDimitry Andric 
11c0981da4SDimitry Andric #include "MinidumpFileBuilder.h"
12c0981da4SDimitry Andric 
13c0981da4SDimitry Andric #include "lldb/Core/ModuleSpec.h"
14c0981da4SDimitry Andric #include "lldb/Core/PluginManager.h"
15c0981da4SDimitry Andric #include "lldb/Core/Section.h"
16c0981da4SDimitry Andric #include "lldb/Target/Process.h"
17ac9a064cSDimitry Andric #include "lldb/Utility/LLDBLog.h"
18ac9a064cSDimitry Andric #include "lldb/Utility/Log.h"
19c0981da4SDimitry Andric 
20c0981da4SDimitry Andric #include "llvm/Support/FileSystem.h"
21c0981da4SDimitry Andric 
22c0981da4SDimitry Andric using namespace lldb;
23c0981da4SDimitry Andric using namespace lldb_private;
24c0981da4SDimitry Andric 
LLDB_PLUGIN_DEFINE(ObjectFileMinidump)25c0981da4SDimitry Andric LLDB_PLUGIN_DEFINE(ObjectFileMinidump)
26c0981da4SDimitry Andric 
27c0981da4SDimitry Andric void ObjectFileMinidump::Initialize() {
28c0981da4SDimitry Andric   PluginManager::RegisterPlugin(
29c0981da4SDimitry Andric       GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
30c0981da4SDimitry Andric       CreateMemoryInstance, GetModuleSpecifications, SaveCore);
31c0981da4SDimitry Andric }
32c0981da4SDimitry Andric 
Terminate()33c0981da4SDimitry Andric void ObjectFileMinidump::Terminate() {
34c0981da4SDimitry Andric   PluginManager::UnregisterPlugin(CreateInstance);
35c0981da4SDimitry Andric }
36c0981da4SDimitry Andric 
CreateInstance(const lldb::ModuleSP & module_sp,lldb::DataBufferSP data_sp,lldb::offset_t data_offset,const lldb_private::FileSpec * file,lldb::offset_t offset,lldb::offset_t length)37c0981da4SDimitry Andric ObjectFile *ObjectFileMinidump::CreateInstance(
38145449b1SDimitry Andric     const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
39c0981da4SDimitry Andric     lldb::offset_t data_offset, const lldb_private::FileSpec *file,
40c0981da4SDimitry Andric     lldb::offset_t offset, lldb::offset_t length) {
41c0981da4SDimitry Andric   return nullptr;
42c0981da4SDimitry Andric }
43c0981da4SDimitry Andric 
CreateMemoryInstance(const lldb::ModuleSP & module_sp,WritableDataBufferSP data_sp,const ProcessSP & process_sp,lldb::addr_t header_addr)44c0981da4SDimitry Andric ObjectFile *ObjectFileMinidump::CreateMemoryInstance(
45145449b1SDimitry Andric     const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
46c0981da4SDimitry Andric     const ProcessSP &process_sp, lldb::addr_t header_addr) {
47c0981da4SDimitry Andric   return nullptr;
48c0981da4SDimitry Andric }
49c0981da4SDimitry Andric 
GetModuleSpecifications(const lldb_private::FileSpec & file,lldb::DataBufferSP & data_sp,lldb::offset_t data_offset,lldb::offset_t file_offset,lldb::offset_t length,lldb_private::ModuleSpecList & specs)50c0981da4SDimitry Andric size_t ObjectFileMinidump::GetModuleSpecifications(
51c0981da4SDimitry Andric     const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
52c0981da4SDimitry Andric     lldb::offset_t data_offset, lldb::offset_t file_offset,
53c0981da4SDimitry Andric     lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
54c0981da4SDimitry Andric   specs.Clear();
55c0981da4SDimitry Andric   return 0;
56c0981da4SDimitry Andric }
57c0981da4SDimitry Andric 
SaveCore(const lldb::ProcessSP & process_sp,const lldb_private::SaveCoreOptions & options,lldb_private::Status & error)58c0981da4SDimitry Andric bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp,
59ac9a064cSDimitry Andric                                   const lldb_private::SaveCoreOptions &options,
60c0981da4SDimitry Andric                                   lldb_private::Status &error) {
61ac9a064cSDimitry Andric   // Output file and process_sp are both checked in PluginManager::SaveCore.
62ac9a064cSDimitry Andric   assert(options.GetOutputFile().has_value());
63ac9a064cSDimitry Andric   assert(process_sp);
64ac9a064cSDimitry Andric 
65ac9a064cSDimitry Andric   // Minidump defaults to stacks only.
66ac9a064cSDimitry Andric   SaveCoreStyle core_style = options.GetStyle();
67b1c73532SDimitry Andric   if (core_style == SaveCoreStyle::eSaveCoreUnspecified)
68b1c73532SDimitry Andric     core_style = SaveCoreStyle::eSaveCoreStackOnly;
69c0981da4SDimitry Andric 
70c0981da4SDimitry Andric   llvm::Expected<lldb::FileUP> maybe_core_file = FileSystem::Instance().Open(
71ac9a064cSDimitry Andric       options.GetOutputFile().value(),
72ac9a064cSDimitry Andric       File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate);
73c0981da4SDimitry Andric   if (!maybe_core_file) {
74c0981da4SDimitry Andric     error = maybe_core_file.takeError();
75c0981da4SDimitry Andric     return false;
76c0981da4SDimitry Andric   }
77ac9a064cSDimitry Andric   MinidumpFileBuilder builder(std::move(maybe_core_file.get()), process_sp);
78c0981da4SDimitry Andric 
79ac9a064cSDimitry Andric   Log *log = GetLog(LLDBLog::Object);
80ac9a064cSDimitry Andric   error = builder.AddHeaderAndCalculateDirectories();
81ac9a064cSDimitry Andric   if (error.Fail()) {
82ac9a064cSDimitry Andric     LLDB_LOGF(log, "AddHeaderAndCalculateDirectories failed: %s",
83ac9a064cSDimitry Andric               error.AsCString());
84c0981da4SDimitry Andric     return false;
85ac9a064cSDimitry Andric   };
86ac9a064cSDimitry Andric   error = builder.AddSystemInfo();
87ac9a064cSDimitry Andric   if (error.Fail()) {
88ac9a064cSDimitry Andric     LLDB_LOGF(log, "AddSystemInfo failed: %s", error.AsCString());
89ac9a064cSDimitry Andric     return false;
90ac9a064cSDimitry Andric   }
91ac9a064cSDimitry Andric 
92ac9a064cSDimitry Andric   error = builder.AddModuleList();
93ac9a064cSDimitry Andric   if (error.Fail()) {
94ac9a064cSDimitry Andric     LLDB_LOGF(log, "AddModuleList failed: %s", error.AsCString());
95ac9a064cSDimitry Andric     return false;
96ac9a064cSDimitry Andric   }
97ac9a064cSDimitry Andric   error = builder.AddMiscInfo();
98ac9a064cSDimitry Andric   if (error.Fail()) {
99ac9a064cSDimitry Andric     LLDB_LOGF(log, "AddMiscInfo failed: %s", error.AsCString());
100ac9a064cSDimitry Andric     return false;
101ac9a064cSDimitry Andric   }
102ac9a064cSDimitry Andric 
103ac9a064cSDimitry Andric   error = builder.AddThreadList();
104ac9a064cSDimitry Andric   if (error.Fail()) {
105ac9a064cSDimitry Andric     LLDB_LOGF(log, "AddThreadList failed: %s", error.AsCString());
106ac9a064cSDimitry Andric     return false;
107ac9a064cSDimitry Andric   }
108ac9a064cSDimitry Andric 
109ac9a064cSDimitry Andric   error = builder.AddLinuxFileStreams();
110ac9a064cSDimitry Andric   if (error.Fail()) {
111ac9a064cSDimitry Andric     LLDB_LOGF(log, "AddLinuxFileStreams failed: %s", error.AsCString());
112ac9a064cSDimitry Andric     return false;
113ac9a064cSDimitry Andric   }
114ac9a064cSDimitry Andric 
115ac9a064cSDimitry Andric   // Add any exceptions but only if there are any in any threads.
116ac9a064cSDimitry Andric   error = builder.AddExceptions();
117ac9a064cSDimitry Andric   if (error.Fail()) {
118ac9a064cSDimitry Andric     LLDB_LOGF(log, "AddExceptions failed: %s", error.AsCString());
119ac9a064cSDimitry Andric     return false;
120ac9a064cSDimitry Andric   }
121ac9a064cSDimitry Andric 
122ac9a064cSDimitry Andric   // Note: add memory HAS to be the last thing we do. It can overflow into 64b
123ac9a064cSDimitry Andric   // land and many RVA's only support 32b
124ac9a064cSDimitry Andric   error = builder.AddMemoryList(core_style);
125ac9a064cSDimitry Andric   if (error.Fail()) {
126ac9a064cSDimitry Andric     LLDB_LOGF(log, "AddMemoryList failed: %s", error.AsCString());
127ac9a064cSDimitry Andric     return false;
128ac9a064cSDimitry Andric   }
129ac9a064cSDimitry Andric 
130ac9a064cSDimitry Andric   error = builder.DumpFile();
131ac9a064cSDimitry Andric   if (error.Fail()) {
132ac9a064cSDimitry Andric     LLDB_LOGF(log, "DumpFile failed: %s", error.AsCString());
133ac9a064cSDimitry Andric     return false;
134ac9a064cSDimitry Andric   }
135c0981da4SDimitry Andric 
136c0981da4SDimitry Andric   return true;
137c0981da4SDimitry Andric }
138