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