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