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 | #include "lldb/Utility/LLDBLog.h" |
18 | |
19 | #include "llvm/Support/FileSystem.h" |
20 | |
21 | using namespace lldb; |
22 | using namespace lldb_private; |
23 | |
24 | LLDB_PLUGIN_DEFINE(ObjectFileMinidump) |
25 | |
26 | void ObjectFileMinidump::Initialize() { |
27 | PluginManager::RegisterPlugin( |
28 | name: GetPluginNameStatic(), description: GetPluginDescriptionStatic(), create_callback: CreateInstance, |
29 | create_memory_callback: CreateMemoryInstance, get_module_specifications: GetModuleSpecifications, save_core: SaveCore); |
30 | } |
31 | |
32 | void ObjectFileMinidump::Terminate() { |
33 | PluginManager::UnregisterPlugin(create_callback: CreateInstance); |
34 | } |
35 | |
36 | ObjectFile *ObjectFileMinidump::CreateInstance( |
37 | const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, |
38 | lldb::offset_t data_offset, const lldb_private::FileSpec *file, |
39 | lldb::offset_t offset, lldb::offset_t length) { |
40 | return nullptr; |
41 | } |
42 | |
43 | ObjectFile *ObjectFileMinidump::CreateMemoryInstance( |
44 | const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp, |
45 | const ProcessSP &process_sp, lldb::addr_t ) { |
46 | return nullptr; |
47 | } |
48 | |
49 | size_t ObjectFileMinidump::GetModuleSpecifications( |
50 | const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, |
51 | lldb::offset_t data_offset, lldb::offset_t file_offset, |
52 | lldb::offset_t length, lldb_private::ModuleSpecList &specs) { |
53 | specs.Clear(); |
54 | return 0; |
55 | } |
56 | |
57 | bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp, |
58 | const lldb_private::FileSpec &outfile, |
59 | lldb::SaveCoreStyle &core_style, |
60 | lldb_private::Status &error) { |
61 | // Set default core style if it isn't set. |
62 | if (core_style == SaveCoreStyle::eSaveCoreUnspecified) |
63 | core_style = SaveCoreStyle::eSaveCoreStackOnly; |
64 | |
65 | if (!process_sp) |
66 | return false; |
67 | |
68 | MinidumpFileBuilder builder; |
69 | |
70 | Target &target = process_sp->GetTarget(); |
71 | |
72 | Log *log = GetLog(mask: LLDBLog::Object); |
73 | error = builder.AddSystemInfo(target_triple: target.GetArchitecture().GetTriple()); |
74 | if (error.Fail()) { |
75 | LLDB_LOG(log, "AddSystemInfo failed: %s" , error.AsCString()); |
76 | return false; |
77 | } |
78 | |
79 | error = builder.AddModuleList(target); |
80 | if (error.Fail()) { |
81 | LLDB_LOG(log, "AddModuleList failed: %s" , error.AsCString()); |
82 | return false; |
83 | } |
84 | |
85 | builder.AddMiscInfo(process_sp); |
86 | |
87 | error = builder.AddThreadList(process_sp); |
88 | if (error.Fail()) { |
89 | LLDB_LOG(log, "AddThreadList failed: %s" , error.AsCString()); |
90 | return false; |
91 | } |
92 | |
93 | // Add any exceptions but only if there are any in any threads. |
94 | builder.AddExceptions(process_sp); |
95 | |
96 | error = builder.AddMemoryList(process_sp, core_style); |
97 | if (error.Fail()) { |
98 | LLDB_LOG(log, "AddMemoryList failed: %s" , error.AsCString()); |
99 | return false; |
100 | } |
101 | |
102 | if (target.GetArchitecture().GetTriple().getOS() == |
103 | llvm::Triple::OSType::Linux) { |
104 | builder.AddLinuxFileStreams(process_sp); |
105 | } |
106 | |
107 | llvm::Expected<lldb::FileUP> maybe_core_file = FileSystem::Instance().Open( |
108 | file_spec: outfile, options: File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate); |
109 | if (!maybe_core_file) { |
110 | error = maybe_core_file.takeError(); |
111 | return false; |
112 | } |
113 | lldb::FileUP core_file = std::move(maybe_core_file.get()); |
114 | |
115 | error = builder.Dump(core_file); |
116 | if (error.Fail()) |
117 | return false; |
118 | |
119 | return true; |
120 | } |
121 | |